youyichannel

志于道,据于德,依于仁,游于艺!

0%

JUC初探-08

线程间通讯方式

线程之间互不干扰,各个线程具有自己的线程栈,存储线程自身的信息。为了使得线程之间实现通信,提供了如下的方式:

1)volatilesynchronizedlock => 保证数据的可见性

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();

// 休眠2秒,确保上述两个线程充分运行
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());

// 防止sleepThread和busyThread立刻退出
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)管道输入、输出流(过时):管道输入/输出流和普通的文件输入/输出流或者网络输入/输出流不同之处在于,它主要用于线程之间的数据传输,传输的媒介是内存。管道输入/输出主要包括了如下四种具体实现:

  • 面向字节的:PipedOutputStreamPipedInputStream
  • 面向字符的:PipedReaderPipedWriter

代码示例:

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/ 强推 河北王校长