3个线程顺序打印ABC10次

今年,唯品会的一道笔试题是三个线程顺序打印ABC10次,当时写得很乱,也写错了,现在给出我的解决方法:

package deadLockThread; public class PrintThread { private static boolean flga1 = true; private static boolean flga2 = false; private static boolean flga3 = false; public static void main(String[] args) { final PrintThread o = new PrintThread(); Thread t1 = new Thread(new Runnable() {@Override public void run() { for (int i = 0; i < 10; i++) { while (true) { synchronized (o) {if (!flga1) { try { o.wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); }} else { System.out.println(Thread.currentThread() .getName()); flga1 = false; flga2 = true; flga3 = false; o.notifyAll(); break; } } }}} }, "A"); Thread t2 = new Thread(new Runnable() {@Override public void run() {for (int i = 0; i < 10; i++) { while (true) { synchronized (o) { if (!flga2) { try { o.wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); }} else { System.out.println(Thread.currentThread() .getName()); flga1 = false; flga2 = false; flga3 = true; o.notifyAll(); break; } }} }} }, "B"); Thread t3 = new Thread(new Runnable() {@Override public void run() {for (int i = 0; i < 10; i++) {while (true) { synchronized (o) { if (!flga3) { try { o.wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); }} else { System.out.println(Thread.currentThread() .getName()); flga1 = true; flga2 = false; flga3 = false; o.notifyAll(); break; } }} }} }, "C"); t1.start(); t2.start(); t3.start(); }}

【3个线程顺序打印ABC10次】其实,原理很简单,用三个标志来判断哪个线程应该wait 。在三个线程里面写入同步代码块,只有取得上面 o对象的对象锁,才能执行,这样保证同一时间只有一个线程在打印。配合wait 和notifyAll 还有三个标志就可以按照顺序打印ABC。
这是网上其他版本,我觉得他比我的好很多,代码简洁而且还是共用一个类,这样再增加线程也容易改动,很巧妙的使用AtomicInteger类 ,AtomicInteger类线程安全,适合在高并发中当计数器.
package com.mythread.test; import java.util.concurrent.atomic.AtomicInteger; public class T { public static void main(String argv[]) {AtomicInteger synObj = new AtomicInteger(0); TestPrint a = new TestPrint(synObj, "A", 0); TestPrint b = new TestPrint(synObj, "B", 1); TestPrint c = new TestPrint(synObj, "C", 2); a.start(); b.start(); c.start(); } }class TestPrint extends Thread { private AtomicInteger synObj; private String name; private int flag; private int count = 0; public TestPrint(AtomicInteger synObj, String name, int flag) { this.synObj = synObj; this.name = name; this.flag = flag; } @Override public void run() { while (true) { synchronized (synObj) { if (synObj.get() % 3 == flag) { synObj.set(synObj.get() + 1); System.out.println(name); count++; synObj.notifyAll(); if (count == 10) { break; } } else { try { synObj.wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } } }




    推荐阅读