Alok Soni
Alok Soni

Reputation: 55

Sequence number using thread Synchronization

I want to print a series of 1 to 100 number using n number of threads (lets take 10 threads for this). Condition is 1st thread will have a sequence number from 1, 11,21....91, 2nd thread will have a sequence 2,12,22.....92 and so on. All other threads will have a sequence number like that. Now I want to print number in sequence 1 to 100. I know we can use synchronization, wait and notify method and using a variable or flag counter but I don't think this is a good idea to use it. I want to use without concurrency (like executors etc) how will I do that. Please suggest.

public class PrintNumberSequenceUsingRunnable {
    int notifyValue = 1;

    public static void main(String[] args) {
        PrintNumberSequenceUsingRunnable sequence = new PrintNumberSequenceUsingRunnable();
        Thread f = new Thread(new First(sequence), "Fisrt");
        Thread s = new Thread(new Second(sequence), "Second");
        Thread t = new Thread(new Third(sequence), "Third");
        f.start();
        s.start();
        t.start();
    }
}

class First implements Runnable {
    PrintNumberSequenceUsingRunnable sequence;

    public First(PrintNumberSequenceUsingRunnable sequence) {
        this.sequence = sequence;
    }

    @Override
    public void run() {
        printFist();
    }

    private void printFist() {
        synchronized (sequence) {
            for (int i = 1; i <= 20; i += 3) {
                while (sequence.notifyValue != 1) {
                    try {
                        sequence.wait();
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
                System.out.println(Thread.currentThread().getName() + " " + i);
                sequence.notifyValue = 2;
                sequence.notifyAll();
            }
        }
    }
}

class Second implements Runnable {
    PrintNumberSequenceUsingRunnable sequence;

    public Second(PrintNumberSequenceUsingRunnable sequence) {
        this.sequence = sequence;
    }

    @Override
    public void run() {
        printSecond();
    }

    private void printSecond() {
        synchronized (sequence) {
            for (int i = 2; i <= 20; i += 3) {
                while (sequence.notifyValue != 2) {
                    try {
                        sequence.wait();
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
                System.out.println(Thread.currentThread().getName() + " " + i);
                sequence.notifyValue = 3;
                sequence.notifyAll();
            }
        }
    }

}

class Third implements Runnable {
    PrintNumberSequenceUsingRunnable sequence;

    public Third(PrintNumberSequenceUsingRunnable sequence) {
        this.sequence = sequence;
    }

    @Override
    public void run() {
        printThrid();
    }

    private void printThrid() {
        synchronized (sequence) {
            for (int i = 3; i <= 20; i += 3) {
                while (sequence.notifyValue != 3) {
                    try {
                        sequence.wait();
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
                System.out.println(Thread.currentThread().getName() + " " + i);
                sequence.notifyValue = 1;
                sequence.notifyAll();
            }
        }
    }
}

Upvotes: 1

Views: 718

Answers (1)

Jazzwave06
Jazzwave06

Reputation: 1851

You need to have values sorted on each threads. Each time a thread writes a number, it triggers an event in an event bus. All threads are subscribed to the event.

You start the system by triggering the event [minimum value - 1].

Each thread will receive a notification that the value [minimum value - 1] has been published. Only the thread that has the value [minimum value] will act and will trigger a new event for value [minimum value + 1].

Edit: I haven't tested it, but something like this.

static void main(String[] args) {
    List<Deque<Integer>> publishQueues = new ArrayList<>();
    for (int i = 1; i <= 10; i++) {
        new Thread(new Worker(i, publishQueues)).start();
    }
}

class Worker implements Runnable {
    Deque subscriberQueue;
    List<Deque<Integer>> publishQueues;
    int i;
    Worker(int i, List<Deque<Integer>> publishQueues) {
        this.i = i;
        this.publishQueues = publishQueues;
        this.subscriberQueue = new ConcurrentLinkedDeque<>();
        this.publishQueues.add(this.subscriberQueue);
    }

    void Run() {
        LinkedList<Integer> ints = new LinkedList<>();
        for (int j = i; j <= 100; j+=10) {
            ints.add(j);
        }

        while (true) {
            Integer publishedInteger = subscriberQueue.poll();
            if (publishedInteger == ints.getFirst() - 1) {
                Integer integer = ints.poll();
                System.out.println(integer);
                for (Dequeu<Integer> publishQueue : publishQueues) {
                    publishQueue.addLast(integer);
                }
            }
        }
    }
}

Upvotes: 1

Related Questions