1.如果主线程中启动了额外线程,默认会等待被启动的所有线程都执行完run()方法才中止JVM。如果一个Thread被标示为Daemon线程,在所有的非Daemon线程都结束时,JVM会自动终止。
2.线程有其优先权,可使用Thread的setPriority()方法设定优先权,可设定值为1(Thread.MIN_PRIORITY)到10(Thread.MAX_PRIORITY),默认是5(Thread.NORM_PRIORITY),超过1到10外的设定值会抛出IllegalArgumentException。数字越大优先权越高,排班器越优先排入CPU,如果优先权相同,则输流执行(Round-robin)。
3.线程因输入输出进入Blocked状态后,在阻断情况结束后,会回到Runnable状态,等待排班器进入执行(Running状态)。一个进入Blocked状态的线程,可以由另一个线程调用该线程的interrupt()方法,让它离开Blocked状态。
4.如果A线程正在运行,流程中允许B线程加入,等到B线程执行完成后再继续A线程流程,则可以使用join()方法完成这个需求。
5.线程完成run()方法后,就会进入Dead,进入Dead(或已经调用过start()方法)的线程不可以再次调用start()方法,否则会抛出IllegalThreadStateException。
6.Thread类上定义有stop()方法,不过被标示为Deprecated,被标示为Deprecated的API,表示过去确实定义过,后来因为会引发某些问题,为了确保向前兼容性,这些API没有直接剔除,但不建议新撰写的程序再使用它。
7.如果要停止线程,最好自行操作,让线程跑完应有的流程,而非调用Thread的stop()方法。不仅停止线程必须自行根据条件操作,程序的暂停、重启,也必须视需求操作,而不是直接调用suspend()、resume()等方法。
8.每个线程都属于某个线程群组,若在main()主流程中产生一个线程,该线程会属于main线程群组。每个线程产生时,都会归入某个线程群组,这视线程是在哪个群组中产生,如果没有指定,则归入产生孩子线程的线程群组。可自行指定线程群组,但线程一旦归入 某个群组,无法更换。
9.线程存取同一对象相同资源时可能引发竞速情况,这样的类为不具备线程安全的类。
10.每个对象都会有个内部锁定,或称为监控锁定,被标示为synchronized的区块将会被监控,任何线程要执行synchronized区块都必须先取得指定的对象锁定。
11.Java的synchronized提供的是可重入同步,即线程取得某对象锁定后,若执行过程中又要执行synchronized,尝试取得锁定的对象又是同一个,则可以直接执行。
12.执行synchronized范围的程序代码期间,若调用锁定对象的wait()方法,线程会释放对象锁定,并进入对象等待集合而处于阻断状态,其他线程可以竞争对象锁定,取得锁定的线程可以执行synchronized范围的程序代码。
13.放在等待集合的线程不会参与CPU排班,wait()可以指定等待时间,时间到之后线程会再次加入排班,如果指定时间0或不指定,则线程会持续等待,直到被中断(调用interrupt())或是告知(notify())可以参与排班。
14.被竞争锁定的对象调用notify()时,会从对象等待集合中随机通知一个线程加入排班,再次执行synchronized前,被通知的线程会与其他线程共同竞争对象锁定;如果调用notifyAll(),所有等待集合中的线程都会被通知参与排班,这些线程会与其他线程共同竞争对象锁定。
15.可以在变量上声明volatile,表示变量是不稳定的、易变的,也就是可能在多线程下存取,这保证变量的可见性,也就是若有线程变动了变量值,另一线程一定可以看到变更。被标示为volatile的变量,不允许线程快取,变量值的存取一定是在共享内存中进行。
未完。。