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/notify
or 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