Java 在多线程程序中未获得预期结果
我并没有得到下面程序的预期结果,我希望生产者和消费者方法都应该以某种顺序执行,但由于某种原因,只有生产者方法被执行 我有两个问题:Java 在多线程程序中未获得预期结果,java,multithreading,Java,Multithreading,我并没有得到下面程序的预期结果,我希望生产者和消费者方法都应该以某种顺序执行,但由于某种原因,只有生产者方法被执行 我有两个问题: 我无法理解这种行为 在main方法的最后一行将两个线程连接在一起工作正常,我无法理解两者之间的区别 public class ProducerConsumer { List<Integer> data = new ArrayList<>(); synchronized void produce() throws Inte
public class ProducerConsumer {
List<Integer> data = new ArrayList<>();
synchronized void produce() throws InterruptedException {
for (int i = 0; i < 10; i++) {
System.out.println("Producing");
data.add(i);
}
wait();
}
synchronized void consume() throws InterruptedException {
System.out.println("Consuming");
data.clear();
notify();
}
public static void main(String[] args) throws InterruptedException {
ProducerConsumer pc = new ProducerConsumer();
Runnable r2 = ()-> {
try {
pc.produce();
} catch (InterruptedException e) {
e.printStackTrace();
}
};
Thread thread1 = new Thread(r2);
thread1.start();
thread1.join();
Runnable r1 = () -> {
try {
pc.consume();
} catch (InterruptedException e) {
e.printStackTrace();
}
};
Thread thread = new Thread(r1);
thread.start();
thread.join();
}
公共类生产者消费者{
列表数据=新的ArrayList();
synchronized void product()引发InterruptedException{
对于(int i=0;i<10;i++){
系统输出打印(“生产”);
数据.添加(i);
}
等待();
}
synchronized void consume()引发InterruptedException{
系统输出打印项次(“消费”);
data.clear();
通知();
}
公共静态void main(字符串[]args)引发InterruptedException{
ProducerConsumer pc=新的ProducerConsumer();
可运行r2=()->{
试一试{
pc.product();
}捕捉(中断异常e){
e、 printStackTrace();
}
};
螺纹1=新螺纹(r2);
thread1.start();
thread1.join();
可运行r1=()->{
试一试{
pc.consume();
}捕捉(中断异常e){
e、 printStackTrace();
}
};
螺纹=新螺纹(r1);
thread.start();
thread.join();
}
输出:
生产
生产
生产
生产
生产
生产
生产
生产
生产
生产product()
方法以wait()
结束。因此它会阻塞,直到某个线程通知它
唯一执行此操作的线程是使用者线程。但是使用者线程只有在生产者线程结束后才由main方法启动。并且在收到通知之前,它不能结束。因此,存在死锁
如果仅在两个线程启动后才join()
,则使用者线程可以启动,而无需等待生产者线程完成。这仍然不能使程序正确,因为
- 您不能保证生产者线程将首先执行
- 在末尾调用wait()是无用的
- 在循环外调用wait()检查条件是不正确的
- 如果您希望方法按顺序执行,那么使用线程是无用的。您可以从主线程开始执行所有操作
- 1)调用
notify()
根本不做任何事情。除非其他线程已经在等待通知
由您来保证,每当您的一个线程调用wait()
,在wait()
开始后的某个时间,其他线程将notify()
同一对象
Oracle很好地解释了o.wait()
和o.notify()
的工作原理,并解释了如何建立这种保证
2) 实际上没有理由这样做:
Thread t = new Thread(r);
t.start();
t.join();
您的程序将使用更少的CPU,它将使用更少的内存,如果您只调用r.run(),它将完成完全相同的任务
相反。线程的整个要点是允许不同的事情发生,如果一个线程在创建一个新线程后立即连接它,那么就没有并发性。新的线程对象将被浪费,除非您对其执行类似操作:
Thread t = new Thread(r);
t.start();
doSomethingElseWhileThread_t_isRunning();
t.join();
3) wait()
和notify()
是线程之间非常低级的通信方式。如果您使用构建在wait()
和notify()
之上的方法,而不是直接使用,那么代码将更易于阅读和理解
给他们打电话
实例特别适合于“生产者/消费者”应用程序