在生产者消费者问题中,线程间通信没有发生,代码在某一点上卡住了



我在java中做生产者消费者问题,但我的代码在System.out.println("In condition in produce method " )这一行卡住了。我认为由于我的代码不能执行consume method。所以谁能帮我这个,告诉我这背后的原因是什么,应该在代码中做什么修改。


import java.util.LinkedList;
class Consumer extends Thread {
public void run()
{
try{
PC p = PC.getInstance();
p.consume();
Thread.sleep(500);
}
catch(Exception e ){
System.out.println(e);
}
}
}
class Producer extends Thread{
public void run (){
PC p = PC.getInstance();
try{
p.produce();
Thread.sleep(500);
}
catch(Exception e){
System.out.println("interrupted");
}
}
}
class PC {
LinkedList a = new LinkedList();
int capacity = 2;
private static PC single_instance = null;
public static PC getInstance()
{
if (single_instance == null)
single_instance = new PC();
return single_instance;
}
public    void consume() throws InterruptedException{
while (true) {
synchronized (this) {
while (a.size() == 0) {
System.out.println("here I am  ");
wait();
}
int val = (int) a.removeFirst();
System.out.println("consumer consumed" + val);
notify();
Thread.sleep(500);
}
}
}
public    void produce() throws InterruptedException {
while(true) {
int value = 0;
synchronized (this) {
while (a.size() == capacity) {
System.out.println("In condition in produce method " );////
wait();
}

System.out.println("producing  value " + value);
a.add(value++);
notify();
System.out.println("after notify in produce method" );
Thread.sleep(500);
}
}
}
}
public class multithreading {
public static void main(String[] args) throws InterruptedException {
Producer p1 = new Producer();
// Producer p2 = new Producer();
Consumer c1 = new Consumer();
p1.start();
c1.start();
p1.join();
c1.join();
}
}

我得到的输出只有

producing  value 0
after notify in produce method
producing  value 0
after notify in produce method
In condition in produce method 
Process finished with exit code 130

这很糟糕:

synchronized(this) {
...
Thread.sleep(...);
...
}

这很糟糕,因为正在睡眠的线程毫无理由地将其他线程锁定在临界区之外。就像两个室友共用一辆车,但其中一个室友拿走钥匙,然后上床睡觉。为什么在第一个室友睡觉的时候,另一个室友不能使用汽车?

这也是不好的:

while (true) {
synchronized(this) {
...
}
}

这是不好的,因为线程离开临界区后做的下一件事是,它试图重新进入临界区。Java的内在锁是不公平的。刚刚离开同步块的线程在试图重新进入时已经在运行。另一个线程被阻塞,等待轮到它。在这种情况下,操作系统总是会选择已经在运行的线程,因为在架构良好的程序中。,在一个室友不带车钥匙睡觉的节目中,这是通常会产生最佳效果的策略。

System.out.println()调用和Thread.sleep()调用移出synchronized(this)块,这将为其他线程提供更好的运行机会:

while (true) {
synchronized(this) {
...
notify();
}
System.out.println("...");
Thread.sleep(500);
}

@Gardener可能已经发现了你的问题:你的单例不是线程安全的(参见上面Gardener的评论)。您应该在一些静态对象上同步静态getInstance()方法。(PC类对象可以工作)

public static PC getInstance()
{
synchronized(PC.class) {
if (single_instance == null) {
single_instance = new PC();
}
return single_instance;
}
}

这不是很好:

...
catch (Exception e) {
System.out.println(e);              // not great
System.out.println("interrupted");  // even less great
}

它不是很好,因为如果发生异常,它只给你最少的信息。这样做是为了获得标准错误输出流上的详细消息,该消息准确地告诉异常发生的位置:

...
catch (Exception e) {
e.printStackTrace();
}

相关内容

  • 没有找到相关文章

最新更新