0%

java多线程编程chap3-4

本文是《java多线程编程核心技术》第三、四章的学习笔记。

线程间通信

等待/通知机制

wait()notify(): wait使线程停止运行,notify使停止的线程继续运行。

注意事项:

  • wait()自动锁放对象锁;notify()不释放;它们必须存在与同步块中。
  • wait 后线程会进入等待池,需要由同一对象的 notify 方法唤醒。
  • 当线程处于wait状态时,调用interrup()方法会出现异常。
  • notify()随机唤醒线程,notifyAll()唤醒全部wait线程.
  • wait(n),使线程等待一段时间,如果没被唤醒,超过时间自动唤醒。

可以用wait()notify()实现生产者和消费者

  • 假死:所有线程都呈WAITING状态。
  • 原因:notify唤醒的是异类,如“生产者”唤醒“生产者”。
  • 解决:将notify()改为notifyAll()

通过管道进行线程间通信:一个线程发送数据到输出管道,另一个线程从输入管道中读数据。

  • 字节流:PipedInputStreamPipedOutputStream
  • 字符流:PipedReaderPipedWriter

方法join的使用

join():使当前线程堵塞,等待线程对象销毁后,再执行当前线程后面的代码。

  • join()interrupt()方法如果彼此遇到,则会出现异常。
  • join(long)可设定等待的时间。注意:join(long)内部使用wait(long)实现,所以join(long)释放锁;而Thread.sleep(long)不会释放锁

ThreadLocal的使用

  • ThreadLocal类:让每个线程可以绑定自己的值
  • 解决get()返回null的问题:覆盖 initialValue()方法使变量具有初始值。
  • InheritableThreadLocal类可在子线程中取得父线程继承下来的值。
  • 还可以对子线程继承下来的值进行修改。

Lock的使用

使用ReentrantLock类

基本用法:

  • 同步: lock() 让线程持有了“对象监视器”,和synchronized一样,线程之间还是顺序执行的。
  • 等待/通知: condition.await() 等待;condition.siganl()通知。注意调用condition.await()前须先调用lock.lock()。它比wait更灵活,因为它可以用不同的condition对象实现通知部分线程。

公平锁和非公平锁

  • 公平锁: new ReentranLock(true) 获取锁是先进先得的
  • 非公平锁: new ReentranLock(false) 获取锁是随机的

一些方法:

  • int getHoldCount() 查询当前线程保持此锁定的个数,也就是调用lock()方法的次数。
  • int getQueueLength() 返回正在等待获取此锁定的线程估计数
  • int getWaitQueueLength(Condition condition) 返回等待与此锁定相关的给定条件Conditon的线程估计数
  • boolean hasQueueThread(Thread thread) 查询指定的线程是否正在等待获取此锁定
  • boolean hasQueueThreads() 查询是否有线程正在等待获取此锁定
  • boolean hasWaiters(Condition) 查询是否有线程正在等待与此锁定有关的condition条件
  • boolean isFair() 判断是不是公平锁
  • boolean isHeldByCurrentThread() 查询当前线程是否保持此锁定
  • boolean isLocked() 查询此锁定是否由任意线程保持
  • void lockInterruptibly() 如果当前线程未被中断,则获取锁定,如果已经被中断则出现异常
  • boolean tryLock() 仅在调用时锁定未被另一个线程保持的情况下,才获取该锁定
  • boolean tryLock(long timeout,TimeUnit unit) 如果锁定在给定等待时间内没有被另一个线程保持,且当前线程未被中断,则获取该锁定
  • void awaitUninterruptibly() await状态时调用thread.interrupt()不会报错

使用ReentrantReadWriteLock类

ReentrantLock类完全互斥,即同一时间只有一个线程可执行lock后面的任务。

ReentrantReadWriteLock特点:

  • 读读共享
  • 写写互斥
  • 写读互斥
  • 读写互斥