Java并发编程线程间通讯实现过程详解

Java中线程间通讯有多种方式,我这里列出一些常用方式,并用代码的方式展示他们是如何实现的:

  • 共享变量

  • wait, notify,notifyAll(这3个方法是Object对象中的方法,且必须与synchronized关键字结合使用)
  • CyclicBarrier、CountDownLatch
  • 利用LockSupport
  • Lock/Condition机制
  • 管道,创建管道输出流PipedOutputStream和管道输入流PipedInputStream

示例一:

package com.zhi.test;

import java.util.concurrent.CountDownLatch;

import java.util.concurrent.atomic.AtomicInteger;

import org.junit.Test;

/**

* Java多线程-线程通讯示例<br>

* flag作为共享变量JobB执行,notify通知Job执行,CountDownLatch通知主线程执行

*

* @author 张远志

* @since 2020年5月4日21:51:24

*

*/

public class ThreadTest2 {

private CountDownLatch latch;

private volatile boolean flag = true;

private Object lock = new Object();

private AtomicInteger num = new AtomicInteger(0);

class JobA implements Runnable {

@Override

public void run() {

synchronized (lock) {

flag = false;

if (num.get() != 3) {

try {

lock.wait(); // wait方法会释放锁

} catch (InterruptedException e) {

}

}

System.out.println("任务A收到通知,继续执行作业");

}

latch.countDown();

}

}

class JobB implements Runnable {

@Override

public void run() {

while (flag) { // 保证JobA先申请到锁

}

synchronized (lock) {

for (int i = 1; i <= 5; i++) {

try {

Thread.sleep(1000);

} catch (InterruptedException e) {

}

int a = num.incrementAndGet();

System.out.println("任务B第" + i + "次执行,num值为:" + a);

if (a == 3) {

lock.notify(); // 唤醒JobB线程,notify方法不会释放锁

}

}

}

latch.countDown();

}

}

@Test

public void test() {

latch = new CountDownLatch(2);

new Thread(new JobA()).start();

new Thread(new JobB()).start();

try {

latch.await(); // 保证2个线程都执行完毕

} catch (InterruptedException e) {

}

}

}

结果输出:

任务B第1次执行,num值为:1

任务B第2次执行,num值为:2

任务B第3次执行,num值为:3

任务B第4次执行,num值为:4

任务B第5次执行,num值为:5

任务A收到通知,继续执行作业

示例二:

package com.zhi.test;

import java.util.concurrent.CountDownLatch;

import java.util.concurrent.locks.LockSupport;

import org.junit.Test;

/**

* Java多线程-线程通讯示例,利用LockSupport

*

* @author 张远志

* @since 2020年5月4日21:51:24

*

*/

public class ThreadTest3 {

private CountDownLatch latch;

private volatile int num = 0;

private Thread ta;

private Thread tb;

class JobA implements Runnable {

@Override

public void run() {

if (num != 3) {

LockSupport.park();

}

System.out.println("任务A收到通知,继续执行作业");

latch.countDown();

}

}

class JobB implements Runnable {

@Override

public void run() {

for (int i = 1; i <= 5; i++) {

try {

Thread.sleep(1000);

} catch (InterruptedException e) {

}

num++;

System.out.println("任务B第" + i + "次执行,num值为:" + num);

if (num == 3) {

LockSupport.unpark(ta); // unpark会立即激活传入线程

}

}

latch.countDown();

}

}

@Test

public void test() {

latch = new CountDownLatch(2);

ta = new Thread(new JobA());

tb = new Thread(new JobB());

ta.start();

tb.start();

try {

latch.await(); // 保证2个线程都执行完毕

} catch (InterruptedException e) {

}

}

}

以上是 Java并发编程线程间通讯实现过程详解 的全部内容, 来源链接: utcz.com/z/332252.html

回到顶部