Flask接口签名sign原理与实例代码浅析
203
2022-12-07
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多线程-线程通讯示例
* 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 + "次执行,numhttp://值为:" + 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) {
}
}
}
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~