java线程间通信

1、Thread.join()

如果一个线程A的run()方法中,调用方法B.join(),那么线程A代码运行到此处时,会等待线程B运行结束后才继续运行。

2、Object.wait()和notify()

一个synchronized代码块中,

  • 如果被共享对象调用wait()方法,这个线程就会释放对象锁,进入wait状态(Thread.sleep()方法不会释放对象锁)
  • 其他线程可以获取对象锁并运行代码
  • 直到在某一个线程内,被共享对象调用notify()方法,唤醒wait状态的线程,它们才能继续运行

注意:
调用一次notify()只能唤醒一个线程,随机选择,如要一次唤醒全部,可调用notifyAll()方法,被唤醒的所有线程再去竞争对象锁。

3、java.util.concurrent.CountDownLatch

倒计时计数器,适用于一个线程等待其他多个线程全都运行结束后再运行的情况。

CountDownLatch cdl = new CountDownLatch(threadsNumber)
  • 其他线程运行完毕后调用countDown()方法使计数-1
  • 在等待的线程里调用await()方法,当计数为0时开始运行


疑惑:
其实我发现在D里依次join A B C其实也可以达到目的啊,并没有出现ABC必须依次运行完毕,D才运行的情况,ABC应该是并行的,为什么说不行呢?

4、java.util.concurrent.CyclicBarrier

CountDownLatch只能让一个线程await(),如果我们需要多个线程互相等待对方准备好后,再同时运行的话呢?

比如,一排运动员都站到起点线上,等待所有人准备好后,再同时起跑的情况。

那就需要使用CyclicBarrier循环栅栏。

CyclicBarrier cb = new CyclicBarrier(threadsNumber)

每个线程各自准备好后,调用CyclicBarrier对象的await()方法,所有线程都准备好之后,才同时开始运行。

5、java.util.concurrent.Callable

Runnable接口的run()方法是没有返回类型的,假如我们需要子线程返回一个结果给父线程,需要实现Callable接口。

Callable接口一般与java.util.concurrent.FutureTask类一起使用,要注意调用FutureTask.get()方法获取运行结果时,会阻塞主线程。

使用方式

实现Callable<V>接口,编写call()方法,返回类型为V

class A implements Callable<Integer>{
    @Override
    public Integer call() throws Exception{
        // 编写任务脚本
    }
}

然后把Callable对象作为参数,实例化FutureTask对象,再把FutureTask交由Thread驱动

FutureTask futureTask = new FutureTask<Integer>(new A());
new Thread(futureTask).start();

通过FutureTask.get()方法取得子线程返回的结果,若子线程还没返回结果,会阻塞主线程运行

try {
    System.out.println("Before futureTask.get()");
    System.out.println("Result:" + futureTask.get());
    System.out.println("After futureTask.get()");
} catch (InterruptedException e) {
    e.printStackTrace();
} catch (ExecutionException e) {
    e.printStackTrace();
}




参考:http://wingjay.com/2017/04/09/Java%E9%87%8C%E5%A6%82%E4%BD%95%E5%AE%9E%E7%8E%B0%E7%BA%BF%E7%A8%8B%E9%97%B4%E9%80%9A%E4%BF%A1%EF%BC%9F/

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值