关于JAVA多线程,这个publisher subscriber程序正确吗? package com.mypublishersubscriber; 导入java.util.LinkedList; 导入java.util.Queue; 导入java.util.Random; 类发布器实现可运行{ 通道对象=null; 随机=新随机(); 公共发布服务器(频道对象){ this.object=对象; } 公开募捐{ 已同步(对象){ while(true){ if(object.queue.size()==object.capacity){ 试一试{ object.wait(); }捕捉(中断异常e){ //TODO自动生成的捕捉块 e、 printStackTrace(); } } int ele=random.nextInt(); System.out.println(“put:+ele”); object.queue.add(ele); object.notify(); } } } } 类使用者实现Runnable{ 通道对象=null; 公共消费者(渠道对象){ this.object=对象; } 公开募捐{ 已同步(对象){ while(true){ if(object.queue.isEmpty()){ 试一试{ object.wait(); }捕捉(中断异常e){ //TODO自动生成的捕捉块 e、 printStackTrace(); } }否则{ int ele=object.queue.poll(); System.out.println(“读取:“+ele”); object.notify(); } } } } } /** *发布者和订阅者将连接到此主类, *将发布到此对象的队列并从此队列中使用 *@author subasish * */ 公共类频道{ Queue Queue=new LinkedList(); 公共最终国际通行能力=1; 公共静态void main(字符串[]args){ 通道对象=新通道(); Publisher Publisher=新发布者(对象); 消费者=新消费者(对象); 线程生产者=新线程(发布者); 线程订户=新线程(使用者); producer.start(); subscriber.start(); } } 我创建了一个Channel类,其“对象”由发布者和订阅者使用 publisher有一个synchronized block in run方法,在该方法中,无限循环检查“通道”队列是否已满,如果已满,则检查调用是否等待“通道”对象并释放锁,否则向其添加元素并通知,最终再次释放锁 使用者还有一个同步块入运行方法,使用无限循环检查“通道”队列是否为空,如果为空,则调用“通道”上的等待并释放锁,否则,将元素添加到“通道”队列并通知
疑问:关于JAVA多线程,这个publisher subscriber程序正确吗? package com.mypublishersubscriber; 导入java.util.LinkedList; 导入java.util.Queue; 导入java.util.Random; 类发布器实现可运行{ 通道对象=null; 随机=新随机(); 公共发布服务器(频道对象){ this.object=对象; } 公开募捐{ 已同步(对象){ while(true){ if(object.queue.size()==object.capacity){ 试一试{ object.wait(); }捕捉(中断异常e){ //TODO自动生成的捕捉块 e、 printStackTrace(); } } int ele=random.nextInt(); System.out.println(“put:+ele”); object.queue.add(ele); object.notify(); } } } } 类使用者实现Runnable{ 通道对象=null; 公共消费者(渠道对象){ this.object=对象; } 公开募捐{ 已同步(对象){ while(true){ if(object.queue.isEmpty()){ 试一试{ object.wait(); }捕捉(中断异常e){ //TODO自动生成的捕捉块 e、 printStackTrace(); } }否则{ int ele=object.queue.poll(); System.out.println(“读取:“+ele”); object.notify(); } } } } } /** *发布者和订阅者将连接到此主类, *将发布到此对象的队列并从此队列中使用 *@author subasish * */ 公共类频道{ Queue Queue=new LinkedList(); 公共最终国际通行能力=1; 公共静态void main(字符串[]args){ 通道对象=新通道(); Publisher Publisher=新发布者(对象); 消费者=新消费者(对象); 线程生产者=新线程(发布者); 线程订户=新线程(使用者); producer.start(); subscriber.start(); } } 我创建了一个Channel类,其“对象”由发布者和订阅者使用 publisher有一个synchronized block in run方法,在该方法中,无限循环检查“通道”队列是否已满,如果已满,则检查调用是否等待“通道”对象并释放锁,否则向其添加元素并通知,最终再次释放锁 使用者还有一个同步块入运行方法,使用无限循环检查“通道”队列是否为空,如果为空,则调用“通道”上的等待并释放锁,否则,将元素添加到“通道”队列并通知,java,multithreading,Java,Multithreading,疑问: 我是否正确使用通道对象 我是否正确使用了“通道”队列,考虑到它与两个线程共享,我是否需要使用volatile或类似的东西 程序正在运行,我得到了正确的输出。 我知道有高级的方法可以做到这一点,但我想了解这种方式的等待和通知。您正在正确使用通道对象,因为您仅在同步块内访问它。对于显式同步,您不需要使用volatile,因为同步操作包括必要的内存屏障 但是,while循环位于synchronized块内,因此一旦一个线程开始运行,另一个线程将等待,直到正在运行的线程调用wait,也就是说
- 我是否正确使用通道对象
- 我是否正确使用了“通道”队列,考虑到它与两个线程共享,我是否需要使用volatile或类似的东西
我知道有高级的方法可以做到这一点,但我想了解这种方式的等待和通知。您正在正确使用通道对象,因为您仅在同步块内访问它。对于显式同步,您不需要使用volatile,因为同步操作包括必要的内存屏障
但是,while循环位于synchronized块内,因此一旦一个线程开始运行,另一个线程将等待,直到正在运行的线程调用wait,也就是说,直到队列已满或为空。您可能会考虑将同步块移到while循环中。吃中断的异常意味着这不会在关机时停止。
package com.mypublishersubscriber;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Random;
class Publisher implements Runnable {
Channel object = null;
Random random = new Random();
public Publisher(Channel object) {
this.object = object;
}
public void run() {
synchronized (object) {
while (true) {
if (object.queue.size() == object.capacity) {
try {
object.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
int ele = random.nextInt();
System.out.println("put: "+ ele);
object.queue.add(ele);
object.notify();
}
}
}
}
class Consumer implements Runnable {
Channel object = null;
public Consumer(Channel object) {
this.object = object;
}
public void run() {
synchronized (object) {
while(true) {
if (object.queue.isEmpty()) {
try {
object.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} else {
int ele = object.queue.poll();
System.out.println("read: "+ele);
object.notify();
}
}
}
}
}
/**
* publisher and subscriber will connect to this main class and<br>
* will publish to this object's queue and consume from this
* @author subhasish
*
*/
public class Channel {
Queue<Integer> queue = new LinkedList<>();
public final int capacity = 1;
public static void main(String[] args) {
Channel object = new Channel();
Publisher publisher = new Publisher(object);
Consumer consumer = new Consumer(object);
Thread producer = new Thread(publisher);
Thread subscriber = new Thread(consumer);
producer.start();
subscriber.start();
}
}