如何使线程等待并在java中通知

时间:2017-04-16 12:28:57

标签: java multithreading synchronized

想象一下,大师要求5个指南帮助5个孩子打印一个有n行的文档。学校里只有一台打印机。现在,线条超过100的孩子应该等到其他孩子完成打印之前。我写了以下代码

public enum Printer {

printer;

public synchronized void print(Kid kid) {
    if(kid.getPagesToPrint()<100){
        System.out.println(kid.getName()+" is printing "+kid.getPagesToPrint()+" pages");
        notify();
    }else{
        try {
            wait();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

}

孩子班

 public class Kid {

private String name;

private int pagesToPrint;

public Kid(String name, int pagesToPrint) {
    super();
    this.name = name;
    this.pagesToPrint = pagesToPrint;
}

public int getPagesToPrint() {
    return pagesToPrint;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public void setPagesToPrint(int pagesToPrint) {
    this.pagesToPrint = pagesToPrint;
}

}

GuideThread类

 public class GuideThread implements Runnable {

private Kid kid;

public GuideThread(Kid kid) {
    super();
    this.kid = kid;
}

@Override
public void run() {
    Printer.printer.print(kid);
}

}

最后是大师班       公共级大师{

public static void main(String[] args) {
    for(int i=1;i<6;i++){
        Thread t = new Thread(new GuideThread(new Kid("Kid_"+i,i*23)));
        t.start();
    }
}

}

当我执行它时,程序等待几分钟然后终止。可以有人更正此代码,以便正在等待的线程 在所有较少的no.of.pages首先打印后,会通知然后打印。

2 个答案:

答案 0 :(得分:1)

这里:

for(int i=1;i<6;i++){
    Thread t = new Thread(new GuideThread(new Kid("Kid_"+i,i*23)));
    t.start();
}

要运行的最后一个主题是要打印更多100页的线程 由于每个线程执行的处理非常短,每个运行线程很可能在下一个线程开始执行之前完成其执行。

如果您希望打印最多页面的孩子在第一个帖子中运行,请将其作为第一个开始。

你的第二个问题是:

public synchronized void print(Kid kid) {
    if(kid.getPagesToPrint()<100){
        System.out.println(kid.getName()+" is printing "+kid.getPagesToPrint()+" pages");
        notify();
    }else{
        try {
            wait();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

if (kid.getPagesToPrint()>=100),孩子必须等待 但如果没有孩子通知他,因为所有孩子都已经完成了他们的印刷,那么最后一个孩子就会被卡住。

所以,if(kid.getPagesToPrint()<100)显然不足以决定是否可以打印 你应该考虑在这种情况下等待孩子的存在。

看起来像是一个家庭作业。我认为这足以引导你。

答案 1 :(得分:0)

可能有一点不同的方法是使用PriorityBlockingQueue https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/PriorityBlockingQueue.html

你能做的是:

  1. 使用PriorityBlockingQueue创建Comparator,使用要打印的页数比较Kids
  2. 实施Printer课程以轮询PriorityBlockingQueue新项目。
  3. 实施GuideThreadPriorityBlockingQueueKids一起提供,并启动Printer
  4. 此方法还允许连续提供Kids,这将根据要打印的页数与队列中的其他Kids进行比较和优先排序。
  5. 它还允许明确区​​分程序的3个方面:生产,消费,优先排序,允许它们单独发展。
  6. 希望这有帮助。