等待/通知机制
不适用等待通知机制
可以用while(true)死循环和sleep()实现
缺点:while(true)的时间间隔过小会消耗资源,过大会抓不住通知的最佳时机,所以不适合线程通信
wait()和notify()实现通信
wait()可以使当前执行代码的线程进行等待。只能再同步代码中调用wait()方法。wait()方法会释放锁。
notify()方法会随机唤醒一个在wait()状态的线程。只能再同步代码中调用notify()方法。notify()方法不会释放锁。notifyAll()会唤醒所有wait()状态的线程。
两个方法都是Object的方法。wait()使线程停止运行,notify使停止的线程继续运行。
wait(long)
等待某一时间内是否有线程对锁进行唤醒,如果超过这个时间则自动唤醒。
管道流
JDK提供了四个类使线程间可以通信
- PipedInputStream 和 PipedOutputStream
- PipedReader 和 PipedWriter
join方法
主线程想等待子线程方法结束后再执行,只需要在主线程中调用子线程的join()即可实现。join的作用是等待线程对象销毁。对象销毁之后继续执行后面的代码。
join和synchronized的区别
join内部使用wait方法进行等待,synchronized关键字使用“对象监视器”原理作为同步。
join(long)和sleep(long)
join(long)内部使用wait(long)来实现,会释放锁。
sleep(long)是Thread的方法,不会释放锁。
ThreadLocal
ThreadLocal类使为了解决每一个线程拥有自己的共享变量问题。ThreadLocal的值只对当前线程可见,在线程之间具有隔离性,每个线程都拥有自己的值。
set()和get()
可以使用set()和get()方法进项赋值和取值,默认get到的值是null。可以继承ThreadLocal类重写initialValue()方法设置get的默认值。
InheritableThreadLocal
类InheritableThreadLocal可以在子线程中取得父线程继承下来的值。
重写InheritableThreadLocal类的initialValue方法可以获取父线程的值。
重写InheritableThreadLocal类的childValue方法可以修改继承到的值。