java多线程之间数据通信


我们知道Java每个线程之间是数据隔离的,那在多线程环境下,两个线程之间,如何进行数据传输呢

下面我们以main线程中新起一个子线程的方式,来模拟两个线程之间数据通信的场景。

使用共享变量/对象

 private static String name = "张三";

    public static void main(String[] args) {

        System.out.println("主线程:name :" + name);

        new Thread(() -> {
            System.out.println("子线程:name :" + name);
        }).start();
    }

当多个线程读取同一个变量/对象时,当其中一个线程修改了 此变量/对象,下次另一个线程在读取时便可以获取到更改后的值。

但是需要注意:

  1. 当多个线程共享同一个数据时,需要考虑并发修改的情况,每一次修改只能由一个线程操作,此时需要对数据进行加锁
  2. 每个线程修改数据,实际修改的是本线程栈中的数据副本,应该使用volatile让其修改对其他线程可见,避免其他线程依旧读取数据副本

父子线程通信

如果两个线程之间是父子关系,可以使用InheritableThreadLocal将父线程中存储的信息传给子线程:

public class MyThreadData {

    public static ThreadLocal<String> local = new ThreadLocal<>();

    public static InheritableThreadLocal<String> inhLocal = new InheritableThreadLocal<>();


    public static String getLocal() {
        return local.get();
    }

    public static String getinhLocal() {
        return inhLocal.get();
    }

}

我们定义一个MyThreadData类,里面有两个变量:ThreadLocal,和InheritableThreadLocal,下面我们对这两种local做下测试
在这里插入图片描述
主线程中分别往ThreadLocal和InheritableThreadLocal中存入name"张三"和"李四"。
我们在子线程中通过读取ThreadLocal并没有获取到信息,但是通过读取InheritableThreadLocal则可以获取到信息。
这是因为ThreadLocal是线程私有的,必须当前线程才能访问到数据,而InheritableThreadLocal则可以将数据传递给子线程。为什么会这样呢?我们来看下一个线程启动时做了哪些事件:
在这里插入图片描述
我们定位到Thread这个类的init方法,可以看到在线程create的时候,会去判断parent.inheritableThreadLocals是否为null,这个parent自然就是我们的主线程了,在不为null的情况下会去调用ThreadLocal.createInheritedMap()方法,入参便是主线程的inheritableThreadLocals对象。

我们再看下createInheritedMap这个方法做了什么事情:
在这里插入图片描述
在这里插入图片描述
这边我们可以看到,最终会去遍历父线程inheritableThreadLocals里面的数据,在子线程中依据父线程数据创建出一个新的entry对象。这样在子线程中自然就持有了父线程数据,且之后两套数据相互独立。

Exchanger

我们也可以使用JDK提供的Exchanger进行数据交换:
在这里插入图片描述
通过demo我们可以看到两个线程之间,相互交换了数据。

在这里插入图片描述
Exchanger ,可以看成是有两个格子,当两个格子被填满之后,进行数据交换。

但是需要注意的是,exchange方法,可以称为交换点,这个方法是阻塞的。如果一个线程已经执行到了exchange方法,会阻塞在这边等待另一个线程也执行exchange方法。
当然我们也可以设置超时时间:
在这里插入图片描述

管道

在这里插入图片描述
需要定义管道的输入流和输出流,主线程向管道中写入"hello",另一个线程从管道中读取出“hello”。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值