java - 使用 wait() 和 notify() VS 信号量在不同上下文中创建的 java 线程间通信哪个更好
问题描述
该程序使用两个线程打印偶数和奇数,使用信号量它工作正常。我尝试根据评论使用同步监视器使用wait()和notify(),所以哪个是没有等待和通知的更好的代码,但线程间通信与使用等待和通知的消息传递相比更少。
package com.stocknap;
import java.util.concurrent.Semaphore;
import java.util.concurrent.atomic.AtomicInteger;
/*
This program prints even and odd sequence using two thread using samaphore
*/
public class Multithreading {
static Semaphore lck = new Semaphore(1,true);
static volatile AtomicInteger currThd = new AtomicInteger(0);
static class evenThread implements Runnable{
Thread another;
public void setAnother(Thread t){
this.another = t;
}
@Override
public void run() {
while(currThd.get() <= 10){
if (currThd.get() % 2==0 ) {
try {
lck.acquire();
System.out.println("acquiring lock by even thread "+another.getName());
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(currThd);
currThd.addAndGet(1);
System.out.println("value increment by even thd "+another.getName());
lck.release();
System.out.println("lck released by even thd "+another.getName());
}
}
}
}
static class oddThread implements Runnable{
Thread another;
public void setAnother(Thread t){
this.another = t;
}
@Override
public void run() {
while(currThd.get() < 10){
if (currThd.get() % 2!=0 ) {
try {
lck.acquire();
System.out.println("acquiring lock by odd thread "+another.getName());
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(currThd);
currThd.addAndGet(1);
System.out.println("value increment by odd thd "+another.getName());
lck.release();
System.out.println("lck released by odd thd "+another.getName());
}
}
}
}
public static void runFlow (String args[]){
evenThread a = new evenThread();
oddThread b = new oddThread();
Thread t1 = new Thread (a);
Thread t2 = new Thread ( b);
a.setAnother(t2);
b.setAnother(t1);
t1.start();
t2.start();
}
}
使用 wait() 和 notify()
/*
This program prints even and odd sequence using two thread with intercommunication of wait and notify
*/
public class MultithreadingCommunication {
static Semaphore lck = new Semaphore(1,true);
static volatile AtomicInteger currThd = new AtomicInteger(0);
static class evenThread implements Runnable{
String msg;
public void setAnother(String t){
this.msg = t;
}
@Override
public void run() {
while(currThd.get() < 10){
synchronized (msg) {
if (currThd.get() % 2 == 0) {
try {
System.out.println("acquiring lock by even thread");
lck.acquire();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(currThd);
currThd.addAndGet(1);
System.out.println("value increment by thd");
lck.release();
System.out.println("lck released by thd");
try {
msg.notify();
} catch (Exception e) {
e.printStackTrace();
}
} else {
try {
msg.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
}
static class oddThread implements Runnable{
String msg;
public void setAnother(String t){
this.msg = t;
}
@Override
public void run() {
while(currThd.get() <= 10){
synchronized (msg){
if (currThd.get() % 2!=0 ) {
try {
System.out.println("acquiring lock by odd thread");
lck.acquire();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(currThd);
currThd.addAndGet(1);
lck.release();
try {
msg.notify();
}
catch (Exception e){
e.printStackTrace();
}
}
else{
try {
msg.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
}
public static void runFlow (String args[]){
evenThread a = new evenThread();
oddThread b = new oddThread();
Thread t1 = new Thread (a);
Thread t2 = new Thread ( b);
String msg = "ok";
a.setAnother(msg);
b.setAnother(msg);
t1.start();
t2.start();
}
}
解决方案
推荐阅读
- arrays - 将 2 个数组数据类型列转换为 Snowflake 中的行
- mysql - mariadb 无法远程连接,或者如果提供了 IP,则无法从同一台机器连接
- string - Rust 中的 `str` 有什么用处吗?
- macos - “STM32CubeIDE”已损坏,无法打开。你应该把它移到废纸篓。(在 Mac 上)
- oracle - 从 Oracle 中的 Timestamp 数据类型列中删除数据不起作用
- python - 模式匹配与 Python 中的字符/数字模式
- vue.js - Vue 组件在部署后不渲染插槽内容
- kdb - KDB 中的分页选项
- vhdl - VHDL 错误 - 未解决的信号“dec”是多重驱动的,这个错误是什么?
- python - pip 安装成功但命令不起作用