java的线程是不允许启动两次的,如果启动两次会被认为是编程错误,而引发异常
synchronized:
局部变量是不会被修改的,而全局变量则很容易就被修改了,而你却还不知道。
(实战发现,有时候先加,有时候先减)
除了ThreadLocal和局部变量安全以外,静态和实例变量都是不安全的
静态变量:很容就发现有时候某线程使用变量时已经被另一个线程修改了。
静态存储方式:因为静态变量是 静态存储方式,对一个变量进行操作 。
局部变量:安全:每个线程执行时将会把局部变量放在各自栈帧的工作内存中,线程间不共享,所以没有安全问题。
ThreadLocal:解决多线程中数据数据因并发产生不一致问题
并发理想:每个任务都作为进程在其自己的地址空间执行,因此进程间不会互相干涉(无彼此间通讯的需要),因为他们都是完全独立的。加快速度,不会有风险
因此,局部变量和threadlocal 是安全的
并发可使我们将程序划分为多个分离的、独立执行的任务
调用有实现了runnable接口的类,直接使用start()方法,该类将调用run()方法,以便这个新线程中启动任务。
一个线程会创造一个单独的执行线程,在对start()的调用完成后,它仍旧会继续存在
Executor:执行器,管理Thread对象,简化并发编程,
1.newCacheThreadPool:为每个任务都创建一个线程
2.newFixedThreadPool:使用了有限的线程集来执行所提交的任务,不会滥用可获得的资源
在线程池中,线程在可能的情况下,都会被自动复用
3.newSingleThreadExecutor():相当于线程数量为1的FixThreadPool():连续执行任务,任务1执行完才会执行任务2,
优点:可确保每次只有一个线程在执行
Callable()
若希望执行完独立的工作后返回一个值,则可以实现Callable接口,而不是Runnable接口
Callable类型返回是从call()中返回,并且必须使用ExecutorServicer.submit()方法调用它
可以调用get()方法获取结果,可以调用具有超时的get(),也可以调用isDone()来查看任务是否已完成
sleep()的调用可以抛出InterruptedException异常,并且将在run中捕获,因为异常不能跨线程传播回main()