-2

我正在开发一个应用程序,其中有 3 个线程。让我们称它们为 a、b、c。

现在我必须开发这样的东西。

最初 b 等待 a 完成其任务,而 c 等待 b。

一旦“a”完成其任务,它就会通知“b”。'b' 应该醒来。现在'a'进入等待状态。'a' 将等到它得到来自 'c' 的确认。

现在 b 完成它的任务并通知'c'。现在“c”被唤醒,“b”进入等待状态。

现在 c 完成任务并确认“a”。现在'c'去等待。

这是一个循环过程,从 a -> b , b -> c, c->a 继续

在此周期之间,所有线程访问队列以进行数据传输,即“a”将数据放入队列 q1,“b”取出数据并将其放入另一个队列 q2,“c”从 q2 取出并处理它并返回给“a”

我在实现这个功能时被卡住了。关于如何做到这一点的任何想法?

谢谢...

4

3 回答 3

1

如果您被允许使用队列(这似乎是家庭作业),那么您可以做一些更优雅的事情。可能由此产生的内部锁定类似于使用信号量的解决方案,但更优雅。

创建 3 个队列,每对进程一个。他们不发送真正的数据,只是开始的信号。

Queue<Integer> queueA2B = new BlockingQueue<Integer>();
Queue<Integer> queueB2C = new BlockingQueue<Integer>();
Queue<Integer> queueC2A = new BlockingQueue<Integer>();

// initialize only the queue that *feeds* A:

queueC2A.put(1);

每个进程必须从其队列中取出一个项目,执行其进程并向下一个进程发送信号。以示例 A 为例:

while (...) {
   queueC2A.take(); // this will block until there's something in the queue
   // do my stuff
   queueA2B.put(1); // send "signal" to the next process
}
于 2012-08-21T10:46:18.867 回答
0

好问题,我写了一个小类,将演示如何使用信号量按顺序运行线程。希望这可以帮助:

public class LockingDemo{

    private Semaphore a = new Semaphore(0);
    private Semaphore b = new Semaphore(0);
    private Semaphore c = new Semaphore(1);

    class A implements Runnable{
        @Override
        public void run() {
            try {
                c.acquire(1);
                System.out.println("Doing A");
                a.release(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    class B implements Runnable{
        @Override
        public void run() {
            try{
                a.acquire(1);
                System.out.println("Doing B");
                b.release(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    class C implements Runnable{
        @Override
        public void run() {
            try{
                b.acquire(1);
                System.out.println("Doing C");
                c.release(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }



    public void a() throws InterruptedException{
        new Thread(new A()).start();
    }

    public void b() throws InterruptedException{
        new Thread(new B()).start();
    }

    public void c() throws InterruptedException{
        new Thread(new C()).start();
    }

    public static void main(String[] args) throws InterruptedException {
        LockingDemo ld = new LockingDemo();
        System.out.println("FIRST RUN CALLING B -> A -> C");
        ld.b();
        ld.a();
        ld.c();
        Thread.currentThread().sleep(2000);
        System.out.println("SECOND RUN CALLING C -> B -> A");
        ld.c();
        ld.b();
        ld.a();
    }
}

这是输出

FIRST RUN CALLING B -> A -> C
Doing A
Doing B
Doing C
SECOND RUN CALLING C -> B -> A
Doing A
Doing B
Doing C
于 2012-08-21T10:15:26.083 回答
0

我会用信号量来做。线程需要自己的信号量,完成后释放下一个信号量。当然,您也可以使用监视器 ( Object#wait() and Object#notify()) 来执行此操作。为了确保它们以循环方式运行,您只需让它们无限循环运行并等待信号量被填充:

import java.util.concurrent.Semaphore;

public class Main {
    private Semaphore a = new Semaphore(1), b = new Semaphore(0), c = new Semaphore(0);

    public class A implements Runnable {
        @Override
        public void run() {
            while (true) {
                try {
                    a.acquire(1);
                    Thread.sleep((long) (Math.random() * 1000));
                    System.out.println("performing task A");
                    b.release(1);
                } catch (InterruptedException e) {}
            }
        }
    }

    public class B implements Runnable {
        @Override
        public void run() {
            while (true) {
                try {
                    b.acquire(1);
                    Thread.sleep((long) (Math.random() * 1000));
                    System.out.println("performing task B");
                    c.release(1);
                } catch (InterruptedException e) {}
            }
        }
    }

    public class C implements Runnable {
        @Override
        public void run() {
            while (true) {
                try {
                    c.acquire(1);
                    Thread.sleep((long) (Math.random() * 1000));
                    System.out.println("performing task C");
                    a.release(1);
                } catch (InterruptedException e) {}
            }
        }
    }

    public void startThreads() {
        new Thread(new A()).start();
        new Thread(new B()).start();
        new Thread(new C()).start();
    }

    public static void main(String[] args) throws InterruptedException {
        Main ld = new Main();
        ld.startThreads();
    }
}

与监视器相比,这个解决方案的一个很酷的地方是,您可以简单地从外部填充一个信号量来启动第二个“线虫”以循环运行。

于 2012-08-21T10:31:12.657 回答