Three thread synchronization

This question was asked in an interview, tried to solve it ... but failed. I was thinking about using CyclicBarrier

There are three streams of T1 fingerprints 1,4,7 ... T2 fingerprints 2,5,8 ... and T3 fingerprints 3,6,9 .... How do you synchronize these three for the print sequence 1,2,3,4 , 5,6,7,8,9 ....

I tried to write and run the following code

public class CyclicBarrierTest {
    public static void main(String[] args) {
        CyclicBarrier cBarrier = new CyclicBarrier(3);
        new Thread(new ThreadOne(cBarrier,1,10,"One")).start();
        new Thread(new ThreadOne(cBarrier,2,10,"Two")).start();
        new Thread(new ThreadOne(cBarrier,3,10,"Three")).start();
    }
}

class ThreadOne implements Runnable {
    private CyclicBarrier cb;
    private String name;
    private int startCounter;
    private int numOfPrints;

    public ThreadOne(CyclicBarrier cb, int startCounter,int numOfPrints,String name) {
        this.cb = cb;
        this.startCounter=startCounter;
        this.numOfPrints=numOfPrints;
        this.name=name;
    }

    @Override
    public void run() {
        for(int counter=0;counter<numOfPrints;counter++)
        {
            try {
            // System.out.println(">>"+name+"<< "+cb.await());
            cb.await();
            System.out.println("["+name+"] "+startCounter);
            cb.await();
            //System.out.println("<<"+name+">> "+cb.await());
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (BrokenBarrierException e) {
            e.printStackTrace();
        }
        startCounter+=3;
        }
    }

}

Output

[Three] 3
[One] 1
[Two] 2
[One] 4
[Two] 5
[Three] 6
[Two] 8
[One] 7
[Three] 9
[One] 10
[Two] 11
[Three] 12
[Two] 14
[One] 13
[Three] 15
[One] 16
[Two] 17
[Three] 18
[Two] 20
[One] 19
[Three] 21
[One] 22
[Two] 23
[Three] 24
[Two] 26
[One] 25
[Three] 27
[One] 28
[Two] 29
[Three] 30

Can someone help me with the right ans?

Similar questions Thread synchronization - Synchronizing three threads for printing 012012012012 ..... does not work

+4
source share
4 answers

As mentioned above, CyclicBarrier is not the best tool for this task.

, , .

:

import java.util.concurrent.BrokenBarrierException; 
import java.util.concurrent.Semaphore;

public class PrintNumbersWithSemaphore implements Runnable {

private final Semaphore previous;

private final Semaphore next;

private final int[] numbers;

public PrintNumbersWithSemaphore(Semaphore previous, Semaphore next, int[] numbers) {
    this.previous = previous;
    this.next = next;
    this.numbers = numbers;
}

@Override
public void run() {

    for (int i = 0; i < numbers.length; i++) {
        wait4Green();

        System.out.println(numbers[i]);

        switchGreen4Next();
    }
}

private void switchGreen4Next() {
        next.release();
}

private void wait4Green() {
    try {
        previous.acquire();
    } catch (InterruptedException e) {
        e.printStackTrace();
        throw new RuntimeException(e);
    }
}

static public void main(String argv[]) throws InterruptedException, BrokenBarrierException {
    Semaphore sem1 = new Semaphore(1);
    Semaphore sem2 = new Semaphore(1);
    Semaphore sem3 = new Semaphore(1);
    sem1.acquire();
    sem2.acquire();
    sem3.acquire();
    Thread t1 = new Thread(new PrintNumbersWithSemaphore(sem3, sem1, new int[] { 1, 4, 7 }));
    Thread t2 = new Thread(new PrintNumbersWithSemaphore(sem1, sem2, new int[] { 2, 5, 8 }));
    Thread t3 = new Thread(new PrintNumbersWithSemaphore(sem2, sem3, new int[] { 3, 6, 9 }));
    t1.start();
    t2.start();
    t3.start();
    sem3.release();

    t1.join();
    t2.join();
    t3.join();
}

}

, , CyclicBarrier:

import java.util.concurrent.BrokenBarrierException; 
import java.util.concurrent.CyclicBarrier;

public class PrintNumbersWithCyclicBarrier implements Runnable {

private final CyclicBarrier previous;

private final CyclicBarrier next;

private final int[] numbers;

public PrintNumbersWithCyclicBarrier(CyclicBarrier previous, CyclicBarrier next, int[] numbers) {
    this.previous = previous;
    this.next = next;
    this.numbers = numbers;
}

@Override
public void run() {

    for (int i = 0; i < numbers.length; i++) {
        wait4Green();

        System.out.println(numbers[i]);

        switchRed4Myself();

        switchGreen4Next();
    }
}

private void switchGreen4Next() {
    try {
        next.await();
    } catch (Exception e) {
        e.printStackTrace();
        throw new RuntimeException(e);
    }
}

private void switchRed4Myself() {
    previous.reset();
}

private void wait4Green() {
    try {
        previous.await();
    } catch (Exception e) {
        e.printStackTrace();
        throw new RuntimeException(e);
    }
}

static public void main(String argv[]) throws InterruptedException, BrokenBarrierException {
    CyclicBarrier cb1 = new CyclicBarrier(2);
    CyclicBarrier cb2 = new CyclicBarrier(2);
    CyclicBarrier cb3 = new CyclicBarrier(2);
    Thread t1 = new Thread(new PrintNumbersWithCyclicBarrier(cb3, cb1, new int[] { 1, 4, 7 }));
    Thread t2 = new Thread(new PrintNumbersWithCyclicBarrier(cb1, cb2, new int[] { 2, 5, 8 }));
    Thread t3 = new Thread(new PrintNumbersWithCyclicBarrier(cb2, cb3, new int[] { 3, 6, 9 }));
    t1.start();
    t2.start();
    t3.start();
    cb3.await();

    t1.join();
    t2.join();
    t3.join();
}

}
+2

CyclicBarrier? :

  • ThreadOne CyclicBarriers
  • ,

    ThreadOne_1 -> ThreadOne_2 -> ThreadOne_3 -> ThreadOne_1 -> etc...

  • (2) CyclicBarrier , CB Thread.

:

, , ()...

, N await . , new CyclicBarrier(3), , await, .

reset()

, ,

+2

, , , wait notifyAll.
A turn , , . , turn ( ), notife while, , .

public class Test2 {

    final static int LOOPS = 10;
    final static int NUM_TREADS = 3;

    static class Sequenced extends Thread {

        static int turn = 0;
        static int count = 0;
        static Object lock = new Object();
        final int order;

        public Sequenced(int order) {
            this.order = order;
        }

        @Override
        public void run() {
            synchronized (lock) {
                try {
                    for (int n = 0; n < LOOPS; ++n) {
                        while (turn != order) {
                            lock.wait();
                        }
                        ++count;
                        System.out.println("T" + (order + 1) + " " + count);
                        turn = (turn + 1) % NUM_TREADS;
                        lock.notifyAll();
                    }
                } catch (InterruptedException ex) {
                    // Nothing to do but to let the thread die.
                }
            }
        }
    }

    public static void main(String args[]) throws InterruptedException {
        Sequenced[] threads = new Sequenced[NUM_TREADS];
        for (int n = 0; n < NUM_TREADS; ++n) {
            threads[n] = new Sequenced(n);
            threads[n].start();
        }
        for (int n = 0; n < NUM_TREADS; ++n) {
            threads[n].join();
        }
    }

}
0
source

As the streams should have the same weight, i.e. first after the second after the third. The following work.

public class MultiThreadSynchronize {

static int index = 0;
static Object lock = new Object();

static class NumberPrinter extends Thread {
    private final int remainder;
    private final int noOfThreads;
    private int value;

    public NumberPrinter(String name, int remainder, int noOfThreads, int value) {
        super(name);
        this.remainder = remainder;
        this.noOfThreads = noOfThreads;
        this.value = value;
    }

    @Override
    public void run() {
        while (index < 20) {
            synchronized (lock) {
                while ((index % noOfThreads) != remainder) {. // base condition where all threads except one waits.
                    try {
                        lock.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                index++;
                System.out.println(getName() + " " + value);
                value += 3;
                lock.notifyAll();
            }
        }
    }
}

public static void main(String[] args) {
    NumberPrinter numberPrinter1 = new NumberPrinter("First Thread", 0, 3, 1);
    NumberPrinter numberPrinter2 = new NumberPrinter("Second Thread", 1, 3, 2);
    NumberPrinter numberPrinter3 = new NumberPrinter("Third Thread", 2, 3, 3);
    numberPrinter1.start(); numberPrinter2.start(); numberPrinter3.start();
}
}
0
source

All Articles