我正在尝试实现一个模型,其中我的主线程将工作委派给工作线程。这些工人线程在无限的循环中运行,定期进行操作,在每个动作之后,他们都在等待(睡觉),直到收到通知以继续主线为止。他们还将信息发送多长时间,直到下一个动作到主线程。主线程决定最短的等待时间在什么时间和同时睡觉。
我设计了我认为它可以工作的方式,但是在运行第一个线程后它会卡住。我想到的第一件事是糟糕的设计,但我仍然相信这也应该起作用。有人有建议如何使它起作用吗?非常感谢
编辑:请参见下面的答案..
在玩不同的方法后,我能够创建一个工作解决方案,这要感谢本文:使用wait/notify vs thread.sleep.sleep()in Java
基本上每个任务(Process1Thread)继承了其自己的监视器/锁定线程类别的父类。任务类中的run()方法在无限循环,同步块(带有监视器/锁定)中运行,并且在每个周期结束时都要通知主线程并等待,直到Mainthread通知他们继续前进环形。
mainthread在hashmap中具有每个任务,作为一个键和时间来等待一个值。它还在同步块中以无限制的块运行,并带有显示器/锁定的任务,以检查每个周期的最短等待时间,而不是用最短的等待时间运行任务,并等待任务才能等待任务通知它继续。每当任务发送通知/等待监视器/锁时,主线程都会继续循环。
对于任何有类似问题的人来说,这是代码:
achread类:
public abstract class AThread extends Thread {
protected boolean firstRun = true;
private final Object monitor = new Object();
protected final Object getMonitor() {
return monitor;
}
}
合法性类别:
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
public class DelegateThread {
public static boolean running = true;
private static Map<AThread, Integer> map;
private static Random rand = new Random();
public static class Process1Thread extends AThread {
@Override
public void run() {
while (running) {
synchronized (getMonitor()) {
try {
int time = map.get(this);
for (int i = 0; i < time; i++) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.print(i + 1 + "-");
}
System.out.println("Finished task [" + this + "]; Time: " + time);
time = randInt(4, 10);
System.out.println("new Time for " + this + " is: " + time);
map.put(this, time);
getMonitor().notify();
getMonitor().wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
public static class Process2Thread extends AThread {... the same as Process1Thread, just different name}
public static class Process3Thread extends AThread {... the same as Process1Thread, just different name}
public static class MainThread extends Thread {
public void run() {
System.out.println("-= Start =-");
Map.Entry<AThread, Integer> min;
while (running) {
try {
min = getMin();
synchronized (min.getKey().getMonitor()) {
System.out.println("--------------------------------------------------");
System.out.println("Sleeping " + min.getKey() + " for: " + min.getValue());
Thread.sleep(min.getValue() * 1000);
if (min.getKey().firstRun) {
min.getKey().start();
min.getKey().firstRun = false;
}
min.getKey().getMonitor().notify();
min.getKey().getMonitor().wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(" -= END =- ");
}
public Map.Entry<AThread, Integer> getMin() {
Map.Entry<AThread, Integer> min = null;
for (Map.Entry<AThread, Integer> entry : map.entrySet()) {
if (min == null || min.getValue() > entry.getValue()) {
min = entry;
}
}
return min;
}
}
public static void main(String[] args) {
MainThread mainThread = new MainThread();
Process1Thread process1Thread = new Process1Thread();
Process2Thread process2Thread = new Process2Thread();
Process3Thread process3Thread = new Process3Thread();
map = new HashMap<>(3);
map.put(process1Thread, 0);
map.put(process2Thread, 1);
map.put(process3Thread, 2);
mainThread.start();
}
public static int randInt(int min, int max) {
return rand.nextInt((max - min) + 1) + min;
}
}