运行(running)的线程执行Thread.sleep(long ms)或t.join()方法,或者发出了I/O请求时,JVM会把该线程置为阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入可运行(runnable)状态。
死亡(dead):线程run()、main() 方法执行结束,或者因异常退出了run()方法,则该线程结束生命周期。死亡的线程不可再次复生。
9.volatile关键字有什么用途,和Synchronize有什么区别volatile用途:
volatile是一个轻量级的Synchronize,保证了共享变量的可见性,能够防止脏读,被volatile关键字修饰的变量,如果值发生了改变,其他线程立刻可见
区别:
(1)volatile只能作用于变量,使用范围较小。synchronized可以用在变量、方法、类、同步代码块等,使用范围比较广。
(2)volatile只能保证可见性和有序性,不能保证原子性。而可见性、有序性、原子性synchronized都可以包证。
(3)volatile不会造成线程阻塞。synchronized可能会造成线程阻塞。
什么是脏读,为什么发生脏读
脏读是指当一个事务正在访问数据,并且对数据进行了修改。而这种修改还没有提交到数据库中,这时,另外一个事务也访问了这个数据,然后使用了这个数据。
10.先行发生原则10.1 程序次序原则:
在一个线程内,按照代码的顺序,书写在前面的代码优先于书写后面的代码;
10.2 管程锁定规则:
一个unlock操作先行发生于后面对同一个锁的lock操作,注意是同一个锁;
10.3 volatile原则:
对于一个volatile变量的写操作先行发生于后面对变量的读操作;
10.4 线程启动原则:
Thread对象的start()方法优先于此线程的每一个动作;
10.5 线程终止原则:
线程中所有的操作都优先发生于此线程的每一个动作;
10.6 对象中断原则:
对象的interrupt()方法的调用优先发生于被中断线程的代码监测中断事件的发生;先中断再检测;
10.7 对象终结原则:
一个对象的初始化(构造函数执行完毕)完成优先发生于它的finalize()方法的开始;
10.8 传递性
如果操作A先行发生于操作B,而操作B又先行发生于操作C,则可以得出操作A先行发生于操作C;
11.并发编程线程安全三要素11.1 原子性(Synchronized, Lock)
即一个操作或者多个操作 要么全部执行并且执行的过程不会被任何因素打断,要么就都不执行。
在Java中,基本数据类型的变量的读取和赋值操作是原子性操作,即这些操作是不可被中断的,要么执行,要么不执行。
11.2 有序性(Volatile,Synchronized, Lock)
即程序执行的顺序按照代码的先后顺序执行。
在Java内存模型中,允许编译器和处理器对指令进行重排序,但是重排序过程不会影响到单线程程序的执行,却会影响到多线程并发执行的正确性。
11.3 可见性(Volatile,Synchronized,Lock)
指当多个线程访问同一个变量时,一个线程修改了这个变量的值,其他线程能够立即看得到修改的值。
当一个共享变量被volatile修饰时,它会保证修改的值会立即被更新到主存,当有其他线程需要读取共享变量时,它会去内存中读取新值。