线程间通讯方式
线程之间互不干扰,各个线程具有自己的线程栈,存储线程自身的信息。为了使得线程之间实现通信,提供了如下的方式:
1)volatile
、synchronized
、lock
=> 保证数据的可见性
2)Object#wait()
、Object#notify()
、Lock#await()
、Lock#signal()
=> 具有通知机制
3)Thread#join()
=>
蕴含隐式唤醒,即等待其他线程执行完成,其他线程会发送唤醒信号
参考文章:详解java
Thread中的join方法 - 知乎 (zhihu.com)
4)ThreadLocal
=>
支持子线程继承的一种形式,即Thread#inheritableThreadLocals
5)线程中断
示例代码:
public class ThreadInterrupted { public static void main(String[] args) throws InterruptedException { Thread sleepThread = new Thread(new Sleep(), "Sleep-Thread"); sleepThread.setDaemon(true); Thread busyThread = new Thread(new Busy(), "Busy-Thread"); busyThread.setDaemon(true); sleepThread.start(); busyThread.start();
TimeUnit.SECONDS.sleep(2); sleepThread.interrupt(); busyThread.interrupt(); System.out.println("Sleep Thread interrupted is " + sleepThread.isInterrupted()); System.out.println("Busy Thread interrupted is " + busyThread.isInterrupted());
TimeUnit.SECONDS.sleep(5); }
static class Sleep implements Runnable { @Override public void run() { while (true) { try { TimeUnit.SECONDS.sleep(100); } catch (InterruptedException e) { throw new RuntimeException(e); } } } }
static class Busy implements Runnable { @Override public void run() { while (true) { } } } }
|
结论:
Thread#sleep()
方法响应中断,肯定会中断sleep。在抛出异常之前,会清理掉中断标志,因此会返回false,因为当前线程已经停止。
- Busy
Thread没有立即响应中断,只是该线程的中断标志位显式为被中断,因此
isInterrupted()
返回的true。
- sleep中的线程被interrupt,先清除中断标志,然后抛出InterruptedException异常。
6)管道输入、输出流(过时):管道输入/输出流和普通的文件输入/输出流或者网络输入/输出流不同之处在于,它主要用于线程之间的数据传输,传输的媒介是内存。管道输入/输出主要包括了如下四种具体实现:
- 面向字节的:
PipedOutputStream
、PipedInputStream
- 面向字符的:
PipedReader
、PipedWriter
代码示例:
public class PipelineIO { public static void main(String[] args) {
try (PipedWriter writer = new PipedWriter(); PipedReader reader = new PipedReader()) { reader.connect(writer); Thread printThread = new Thread(new Print(reader), "Print-Thread"); printThread.start(); int receive; while ((receive = System.in.read()) != -1) { writer.write(receive); } } catch (IOException e) { throw new RuntimeException(e); } }
static class Print implements Runnable { private final PipedReader reader;
public Print(PipedReader reader) { this.reader = reader; }
@Override public void run() { int receive; try { while ((receive = reader.read()) != -1) { System.out.print((char) receive); } } catch (IOException e) { throw new RuntimeException(e); } } } }
|
资料:https://www.bilibili.com/video/BV1VN4y1m7km/ 强推 河北王校长