Talk about three threads together in order to print the story, 2, 3 ...

Three threads and then click Print, 2, 3 ... this issue, as is often face questions, topics are as follows:

Three threads, a thread is responsible for printing 1,4,7, ......; the second is responsible for printing 2,5,8, ......, the third responsible for printing 3,6,9, ......, requested by the console 1,2,3,4,5,6 ...... sequentially output.

This topic is certainly to start three threads, how to let these three threads "collaboration" Print 1,2,3 order it? In broad terms, this kind of "cooperation" can be divided into the following two:

  • Competitive : Each thread rushing to print, if you should find yourself printing, preparing the next round of looting. Because we are all competitive, thus requiring a locking mechanism to protect.
  • Collaborative type : After printing the current thread thread next thread to notify a print, this need to confirm a good time to print the first thread. Because it is a synergistic type of locking mechanism therefore can not be protected, but requires a notification mechanism.

Competitive Printing

Competitive print multiple threads, the code is easy to understand the advantages and disadvantages are fighting for is the CPU thread scheduling, the results of the thread CPU scheduling delay is not possible when a thread of the print, the results of other threads are scheduled but the CPU Since the printing operation can not be performed while the fighting continued, resulting in a waste of CPU performance. Sample code is as follows:

public class DemoTask implements Runnable {

    // 这里将lock对象换成 Lock(ReentrantLock) 进行lock/unlock也是可以的
    private static final Object lock = new Object();
    private static final int MAX = 1024;
    private static int current = 1;

    private int index;
    public DemoTask(int index) {
        this.index = index;
    }

    @Override
    public void run() {
        while (current <= MAX) {
            synchronized (lock) {
                if ((current <= MAX) && (current % 3 == index)) {
                    System.out.println(current++);
                }
            }
        }
    }

    public static void main(String[] args) throws Exception {
        List<Thread> threadList = Arrays.asList(
                new Thread(new DemoTask(0)),
                new Thread(new DemoTask(1)),
                new Thread(new DemoTask(2))
        );

        threadList.forEach(Thread::start);
        for (Thread thread : threadList) {
            thread.join();
        }
    }
}

Collaborative type Print

Co-type printing multiple threads, each thread advantage of using the "notification" mechanism for collaborative division of labor, higher theoretical efficiency, but to use the "notice" corresponding mechanisms. On how to "notice", the first is the use of Java objects wait/notifyor Conditon object await/signal, the second is to submit an event or task (such as by submitting "to be printed, the number" this task to the next thread).

In a second embodiment below code analysis, such as the current through the thread to the next thread submit a "number to be printed" job, it is easy to think of using a thread pool contains only one of the threads is achieved, the following sample code:

public class DemoTask implements Runnable {

    // 主线程要等待线程打印完毕,使用CountDownLatch通知机制
    private static CountDownLatch countDownLatch = new CountDownLatch(1);
    private static List<ExecutorService> threadList = new ArrayList<>();
    private static final int MAX = 1024;
    private static int current = 1;

    @Override
    public void run() {
        if (current <= MAX) {
            System.out.println(current++);
            threadList.get(current % threadList.size()).submit(new DemoTask());
        } else {
            countDownLatch.countDown();
        }
    }

    public static void main(String[] args) throws InterruptedException {
        for (int i = 0; i < 3; i++) {
            threadList.add(Executors.newFixedThreadPool(1));
        }

        threadList.get(0).submit(new DemoTask());
        countDownLatch.await();
        threadList.forEach(ExecutorService::shutdown);
    }
}

Recommended Reading

Guess you like

Origin www.cnblogs.com/luoxn28/p/12385961.html