Java线程之间通信

Java线程之间通信

一般而言,线程都有自己私有的线程上下文。但是当我们需要多个线程进行相互协作的时候,进行线程之间的通信就十分重要了。

锁与同步

线程同步可以认为是线程之间按照一定的顺序执行,为了达到线程同步,我们可以通过锁来实现。

等待/通知机制

Java多线程的等待通知是基于Object类的wait()以及notify(),notifyAll()方法来是实现的

notify()会随机唤醒一个正在等待的线程,而notifyAll()会唤醒所有正在等待的线程。

假设线程A持有了一个锁lock,使用了lock.wait()让自己进入等待状态,那么这个时候lock锁是被释放了的。

线程B获取这个锁之后,使用lock.notify()通知之前持有lock锁并进入等待状态的线程A,可以继续往下执行力。(但是这个时候线程B并没有释放lock锁)

信号量

信号量主要是控制最多N个线程同时访问资源。以停车场为例,假设一个停车场一共有8个车位,现在已经停了6个车位了,然后又来了两个车子刚好可以停。接着又来了一辆,只能等待着有车子离开,留出空车位。

管道

当我们需要从一个线程向另一个线程发送消息、文件的时候就可以使用管道通信了。

Java为我们提供了PipedWriter、PipedReader、PipedOutputStream、PipedInputStream。其中前面两个是基于字符,后面的则是基于字节流。

以下代码示例了如何使用基于字符进行线程交流。

public class Pipe {
    static class ReaderThread implements Runnable {
        private PipedReader reader;

        public ReaderThread(PipedReader reader) {
            this.reader = reader;
        }

        @Override
        public void run() {
            System.out.println("this is reader");
            int receive = 0;
            try {
                while ((receive = reader.read()) != -1) {
                    System.out.print((char)receive);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    static class WriterThread implements Runnable {

        private PipedWriter writer;

        public WriterThread(PipedWriter writer) {
            this.writer = writer;
        }

        @Override
        public void run() {
            System.out.println("this is writer");
            int receive = 0;
            try {
                writer.write("test");
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    writer.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public static void main(String[] args) throws IOException, InterruptedException {
        PipedWriter writer = new PipedWriter();
        PipedReader reader = new PipedReader();
        writer.connect(reader); // 这里注意一定要连接,才能通信

        new Thread(new ReaderThread(reader)).start();
        Thread.sleep(1000);
        new Thread(new WriterThread(writer)).start();
    }
}

// 输出:
this is reader
this is writer
test
  1. 线程ReaderThread开始执行,

  2. 线程ReaderThread使用管道reader.read()进入”阻塞“,

  3. 线程WriterThread开始执行,

  4. 线程WriterThread用writer.write(“test”)往管道写入字符串,

  5. 线程WriterThread使用writer.close()结束管道写入,并执行完毕,

  6. 线程ReaderThread接受到管道输出的字符串并打印,

  7. 线程ReaderThread执行完毕。

Ref

  1. https://redspider.gitbook.io/concurrent/di-yi-pian-ji-chu-pian/5
  2. https://segmentfault.com/a/1190000038971320
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值