Java多线程编程(第三章)

1. 线程间通信

线程之间可以互相通信和协作

  • wait()方法的作用是使当前执行代码的线程进行等待,wait()方法是Object类的方法,在wait()方法所在的代码行处停止执行,直到接到通知或被中断终止。在调用wait()方法前,线程必须获得该对象的锁,即只能在同步方法或同步块中调用wait()方法。 在执行wait()方法后,当前线程会释放锁。

  • notify()方法也要在同步方法或同步块中调用,即在调用前,线程必须获得该对象的锁。

  • 线程进入Runnable(就绪)状态的情况

    1. 调用sleep()方法后经过的时间超过了指定的休眠时间
    2. 线程调用的阻塞IO已经返回,阻塞方法执行完毕
    3. 线程成功获得了对象的锁
    4. 线程正在等待某个通知,其他线程发出了通知
  • 出现Blocked阻塞状态的情况

    1. 线程调用sleep()方法,主动放弃占用的处理器资源
    2. 线程调用了阻塞式IO方法,在该方法返回之前,该线程被阻塞
    3. 线程试图获得一个对象的锁,但该锁已被其他线程持有
    4. 线程等待某个通知
  • 每个锁对象都有两个队列,一个是就绪队列,一个是阻塞队列;就绪队列存储了将要获得锁的线程,阻塞队列存储了被阻塞的线程;

  • wait释放锁,notify不释放锁

  • 当线程呈wait状态时,调用线程对象的interrupt()方法会出现异常

interrupted静态方法:测试当前线程(current thread)是否是中断状态,执行后将状态标识清除,置为false。
isInterrupted实例方法: 测试线程Thread对象(this thread)是否是中断状态,不会清除标识状态。
  • notify只随机唤醒一个线程,notifyAll唤醒全部线程

  • wait(long timeout)
    等待某一时间内是否有线程对其发出通知,如果超过了这个时间,则自动唤醒

  • 等待wait的条件发生改变了, 会导致流程改变,所以用while来判断条件

  • 生产者/消费者模式

    1. 一个生产者,一个消费者
    2. 多个生产者,多个消费者, “假死”的现象其实就是所有线程进入WAITING等待状态 解决用 while 和 notifyAll
    3. 一个生产者,多个消费者
    4. 多个生产者,一个消费者

2. 通过管道进行线程间通信

管道流(pipeStream)是一种特殊的流,用于在不同线程间直接传送数据。一个线程发送数据到输出管道,另一个线程从输入管道读数据。
1. PipedInputStream 和 PipedOutStream
2. PipedReader 和 PipedWriter

PipedInputStream inputStream = new PipedInputStream();
PipedOutputStream outputStream = new PipedOutputStream();
inputStream.connect(outputStream);//进行连接

3. 方法join的使用

  • join的作用是等待线程对象销毁
  • join在内部使用wait()方法进行等待,所以具有释放锁的特点
  • 方法join()和interrupt()方法相遇,则会抛出异常
  • join(long timeout)
    设定等待的时间
  • 特殊情况:b.join(2000)方法先抢到B锁,然后将B锁释放
thread.join()

4. ThreadLocal的使用

每一个线程都有自己的共享变量;ThreadLocal类解决的是变量在不同线程间的隔离性,不同的线程拥有自己的值。

ThreadLocal<Date> local = new ThreadLoacl<>();
//重写initalValue()方法,可以设置默认初始值

5. InheritableThreadLocal的使用

作用是让子线程从父线程中取得值
- 使用InheritableThreadLocal类需要注意一点的是,如果子线程在取得值的同时,主线程将InheritableThreadLocal中的值进行修改,那么子线程获取的值还是旧值。

//重写childValue(Object parentValue)方法 可以在子类中获取新值

你可能感兴趣的:(Java多线程编程(第三章))