线程同步化(Thread syncronization)

2019-09-21 09:59发布

我正在开发中,我有3个线程的应用程序。 让我们称他们为A,B,C。

现在,我要发展这样的事情。

最初的B等待完成其任务,和C等待湾

只要“一”完成其任务,它通知“B”。 “B”应该警醒。 现在,“一个”去等待状态。 “A”将等待,直到它从“C”的确认。

现在,b完成其任务,并通知“C”。 现在,“C”唤醒和“b”进入等待状态。

现在ç完成任务,并确认为“A”。 现在,“C”去等待。

这是循环过程,并从继续 - > B,B - > C,C->一

在这个周期之间进行数据传输,即所有线程访问队列“一”把数据在队列Q1,“B”取它,而在另一个队列Q2提出,“C”从Q2和过程它提取并给回“A”

我同时实现该功能卡。 关于如何任何想法可以做什么?

谢谢...

Answer 1:

如果你被允许使用队列 (好像作业),那么你可以做一些事情更优雅。 可能产生的内部lockings类似旗语的解决方案,但更优雅。

创建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);

每个进程必须采取一个项目从它的队列,做它的进程和发送信号到下一个。 举例答:

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
}


Answer 2:

有趣的问题,我已经写了一个小的类,将演示如何信号灯可用于序列中运行的线程。 希望这可以帮助:

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


Answer 3:

我将与信号灯做到这一点。 线程是需要自己的信号,完成后,发布下一个信号。 你当然也可以做到这一点与显示器( 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();
    }
}

与相对于显示器这个解决方案的很酷的事情是,你可以简单地从外面填补了一个信号启动第二个“线程虫”,以跑在圈子里。



文章来源: Thread syncronization