二、线程
1.将一个线程标记成daemon(守护神、守护进程)线程,意味着当主线程结束,并且没有其它正在运行的非daemon线程时,该daemon线程也会自动结束。这句话正确。 daemon线程是守护线程,当主线程结束时,守护线程会自动结束。
2.
CyclicBarrier(栅栏):可以让一组线程等待其他线程。 CountDownLatch(闭锁): 可以让一组线程等待某个事件发生。所以
CyclicBarrier和CountDownLatch都可以让一组线程等待其他线程这句话对的。
3.同步器是一些使线程能够等待另一个线程的对象,允许它们协调动作。最常用的同步器是CountDownLatch和Semaphore,不常用的是Barrier 和Exchanger。CyclicBarrier 主要的方法就是一个:await()。await() 方法每被调用一次,计数便会减少1,并阻塞住当前线程。当计数减至0时,阻塞解除,所有在此 CyclicBarrier 上面阻塞的线程开始运行。直译过来就是倒计数(CountDown)门闩(Latch)。倒计数不用说,门闩的意思顾名思义就是阻止前进。在这里就是指 CountDownLatch.await() 方法在倒计数为0之前会阻塞当前线程。
4. ThreadLocal的类声明:
5.后台线程:指为其他线程提供服务的线程,也称为守护线程。JVM的垃圾回收线程就是一个后台线程。 前台线程:是指接受后台线程服务的线程,其实前台后台线程是联系在一起,就像傀儡和幕后操纵者一样的关系。可以通过isDaemon()和setDaemon()方法来判断和设置一个线程是否为后台线程。
main()函数即主函数,是一个前台线程,前台进程是程序中必须执行完成的,而后台线程则是java中所有前台结束后结束,不管有没有完成,后台线程主要用与内存分配等方面。
6. volatile关键字
(3)由于及时更新,很可能导致另一线程访问最新变量值,无法跳出循环的情况,多线程下计数器必须使用锁保护。
(4) 稍弱的同步机制,volatile变量,用来确保将变量的更新操作通知到其他线程。
当变量被申明为volatile后,编译器与运行时都会注意到这个变量是共享的,因此不会将该变量上的操作与其他内存操作一起重排序。
volatile不会被缓存在寄存器或者其他处理器中,因此在读取volatile类型的变量时总会返回最新写入的值。
加锁机制既可以确保可见性也可以确保原子性,而volatile变量只能保证可见性。
7.
进入”Dead”状态的线程 不一定 被垃圾回收器回收。当对象变成(GC Roots)不可达时,GC会判断该对象是否覆盖了finalize方法,若未覆盖,则直接将其回收。否则,若对象未执行过finalize方法,将其放入F-Queue队列,由一低优先级线程执行该队列中对象的finalize方法。执行finalize方法完毕后,GC会再次判断该对象是否可达,若不可达,则进行回收,否则,对象“复活”。
垃圾回收线程的priority(优先级)相当相当低。
8.
lockInterruptibly()方法比较特殊,当通过这个方法去获取锁时,如果线程正在等待获取锁,则这个线程能够响应中断,即中断线程的等待状态。也就使说,当两个线程同时通过lock.lockInterruptibly()想获取某个锁时,假若此时线程A获取到了锁,而线程B只有在等待,那么对线程B调用threadB.interrupt()方法能够中断线程B的等待过程。
由于lockInterruptibly()的声明中抛出了异常,所以lock.lockInterruptibly()必须放在try块中或者在调用lockInterruptibly()的方法外声明抛出InterruptedException。
因此lockInterruptibly()一般的使用形式如下: lock.lockInterruptibly(); ................最后别忘了关闭 unlock.
10. 进程是程序在某个数据集合上的一次运行活动;线程是进程中的一个执行路径。
进程是cpu资源分配的最小单位,线程是cpu调度的最小单位。
进程之间不能共享资源,而线程共享所在进程的地址空间和其它资源。同时线程还有自己的栈和栈指针,程序计数器等寄存器。
进程有自己独立的地址空间,而线程没有,线程必须依赖于进程而存在。
进程间的切换,开销较大,线程之间的切换开销较小。进程之间的通信较为复杂,线程之间的通信开销较小。
11.java线程之间 如何通信
(1)sychronized加锁,本质上相当于 “共享内存”。
(2)wait、notify
(3)管道流, java.io.PipedInputStream或者java.io.PipedOutputStream