Java:实施代表人线程,工人在无限循环中相互等待



我正在尝试实现一个模型,其中我的主线程将工作委派给工作线程。这些工人线程在无限的循环中运行,定期进行操作,在每个动作之后,他们都在等待(睡觉),直到收到通知以继续主线为止。他们还将信息发送多长时间,直到下一个动作到主线程。主线程决定最短的等待时间在什么时间和同时睡觉。

我设计了我认为它可以工作的方式,但是在运行第一个线程后它会卡住。我想到的第一件事是糟糕的设计,但我仍然相信这也应该起作用。有人有建议如何使它起作用吗?非常感谢

编辑:请参见下面的答案..

在玩不同的方法后,我能够创建一个工作解决方案,这要感谢本文:使用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;
    }
}

最新更新