开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第9天,点击查看活动详情
1.java线程间的通信方式
今天先简单说一下,以后会详细讲述。
1. volitate 、synchronize、lock。(都保证可见性)
2. wait、notify、await() 、 signal
3. 管道输入、输出流 (示例代码:PipeInOut.java)
管道输入/输出流和普通的文件输入/输出流或者网络输入/输出流不同之处在于,它主要用于线程之间的数据传输,而传输的媒介为内存。 管道输入/输出流主要包括了如下4种具体实现:PipedOutputStream、PipedInputStream、PipedReader和PipedWriter,前两种面向字节,而后两种面向字符。
4. Thread.join() : 隐式唤醒。等待其他线程执行完成,其他线程会发送唤醒信号。
5. ThradLocal() ---》支持子线程继承的一种形式。埋点。
6. 线程中断
这里我们就说一下第三点和第6点,前1/2/5点以后会详细讲解。
2简单说一下管道输入、输出流
这个不是重点,大概了解一下即可。
public class PipeInOut {
public static void main(String[] args) throws IOException {
PipedWriter out = new PipedWriter();
PipedReader in = new PipedReader();
// 将输出流和输入流进行连接,否则在使用时会抛出IOException
out.connect(in);
Thread printThread = new Thread(new Print(in), "PrintThread");
printThread.start();
int receive = 0;
try {
while ((receive = System.in.read()) != -1) {
out.write(receive);
}
} finally {
out.close();
}
}
static class Print implements Runnable {
private PipedReader in;
public Print(PipedReader in) {
this.in = in;
}
public void run() {
int receive = 0;
try {
while ((receive = in.read()) != -1) {
System.out.print((char) receive);
}
} catch (IOException ex) {
}
}
}
}
我们可以看到效果如下,我输入一个Hello,程序也跟着输入一个Hello,程序把输入的给了主线程的receive变量,out再调用write,然后到了另一个线程去调用in的read()方法去读取这个write的东西。
3线程中断
我下面贴上示例代码,可能有点长,但是很简单:
public class ThreadInterrupted {
public static void main(String[] args) throws InterruptedException {
// sleepThread不停的尝试睡眠
Thread sleepThread = new Thread(new SleepRunner(), "SleepThread");
sleepThread.setDaemon(true);
Thread busyThread = new Thread(new BusyRunner(), "BusyThread");
busyThread.setDaemon(true);
sleepThread.start();
busyThread.start();
// 休眠5秒,让sleepThread和busyThread充分运行
TimeUnit.SECONDS.sleep(5);
sleepThread.interrupt();
busyThread.interrupt();
//sleep方法响应中断,肯定会中断sleep。在抛出异常之前,会清理掉我们的 中断标志。 会返回false,因为当前线程已经停止了。
System.out.println("SleepThread interrupted is " + sleepThread.isInterrupted());
// busy thread ,没有立即响应中断,知识他的中断标志位 显示 被中断,这个是isInterrupted会返回true。
System.out.println("BusyThread interrupted is " + busyThread.isInterrupted());
// 防止sleepThread和busyThread立刻退出
TimeUnit.SECONDS.sleep(5);
}
static class SleepRunner implements Runnable {
@SneakyThrows
@Override
public void run() {
while (true) {
// 先清除标志,后抛异常、(sleep)
TimeUnit.SECONDS.sleep(100);
}
}
}
static class BusyRunner implements Runnable {
@Override
public void run() {
while (true) {
}
}
}
}
我们可以看到效果如下:
线程中断总结来说还是两句话:
sleep方法响应中断,肯定会中断sleep。在抛出异常之前,会清理掉我们的 中断标志。 会返回false,因为当前线程已经停止了。
busy thread ,没有立即响应中断,知识他的中断标志位 显示 被中断,这个是isInterrupted会返回true。