7.2.10.1有T1、T2、T3三个线程,如何保证T2在T1执行完后执行,T3在T2执行完后执行?
用join语句,在t3开始前join t2,在t2开始前join t1。
不过,这会破坏多线程的并发性,不建议这样做。
7.2.10.2 wait和sleep方法有什么不同?
对于sleep()方法,我们首先要知道该方法是属于Thread类中的。而wait()方法,则是属于Object类中的。
sleep()方法导致了程序暂停执行指定的时间,让出cpu该其他线程,但是他的监控状态依然保持者,当指定的时间到了又会自动恢复运行状态。在调用sleep()方法的过程中,线程不会释放对象锁。
而当调用wait()方法的时候,线程会放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象调用notify()方法后本线程才获取对象锁进入运行状态。
7.2.10.3 用Java多线程的思路解决生产者和消费者问题。
在本书7.2.4部分里,给出了通过wait和notify解决生产者消费者问题的相关代码,大家可以读下。
7.2.10.4 如何在多个线程里共享资源。
本书提到了synchronized,Lock和volatile三种方法,通过它们,可以控制多线程的并发,大家可以参考下。
7.2.10.5 notify和notifyAll方法有什么差别和联系?
通过wait和notify方法,我们同样可以通过控制“锁”的方式来实现多线程的并发管理。这两个方法需要放置在synchronized的作用域里(比如synchronized作用的方法或代码块里),一旦一个线程执行wait方法后,该线程就会释放synchronized所关联的锁,进入阻塞状态,所以该线程一般无法再次主动地回到可执行状态,一定要通过其它线程的notify(或notifyAll)方法唤醒它。
一旦一个线程执行了notify方法,则会通知那些可能因调用wait方法而等待对象锁的其他线程,如果有多个线程等待,则会任意挑选其中的一个线程来发出唤醒通知,这样得到通知的线程就能继续得到对象锁从而继续执行下去。
对于notifyAll,该方法会让所有因wait方法进入到阻塞状态的线程退出阻塞状态,但由于这些线程此时还没有获取到对象锁,因此还不能继续往下执行,它们会去竞争对象锁,如果其中一个线程获得了对象锁,则会继续执行,在它退出synchronized代码释放锁后,其它的已经被唤醒的线程则会继续竞争,以此类推,直到所有被唤醒的线程都执行完毕。
7.2.10.6 synchronized 和 ReentrantLock有什么不同?它们各自的适用场景是什么?
synchronized可以作用在方法和代码块上,但无法锁住由多个方法组成的业务块,而ReentrantLock可以保证业务层面的并发。
7.2.10.7 synchronized如果作用在一段代码上,那么是锁什么?
是锁方法所在的对象