1. 利用synchronized
思路:
打印A时,必须先拿到 B,C锁, 打印完了之后,释放A锁,然后打印B的线程拿到A锁后就可以打印B,依次循环。
public class MythreadPrinter implements Runnable { private String name; private Object prev; private Object self; @Override public void run() { int count = 3; while (count>0){ synchronized (prev){ synchronized (self){ System.out.println(name); count--; self.notify(); } try { prev.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } } public static void main(String[] args) throws Exception{ Object a = new Object(); Object b = new Object(); MythreaPrinter pa = new MythreaPrinter("A",b,a); MythreaPrinter pb = new MythreaPrinter("B",a,b); new Thread(pa).start(); Thread.sleep(100); new Thread(pb).start(); Thread.sleep(100); } }
2.利用lock
public class MythreadPrinter_lock { private Lock lock = new ReentrantLock(); private Condition conditionA = lock.newCondition(); private Condition conditionB = lock.newCondition(); private Condition conditionC = lock.newCondition(); public String cur_name = "A"; public static void main(String[] args) { MythreadPrinter_lock myPrinter = new MythreadPrinter_lock(); ExecutorService es = Executors.newFixedThreadPool(3); es.submit(myPrinter.new PrinterA()); es.submit(myPrinter.new PrinterB()); es.submit(myPrinter.new PrinterC()); es.shutdown(); } public class PrinterA implements Runnable{ @Override public void run() { for (int i = 1; i <= 5; i++) { lock.lock(); try { while(cur_name != "A"){ try { conditionA.await(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("第"+i+"次打印"+cur_name); cur_name = "B"; conditionB.signal(); }catch (Exception e){ }finally { lock.unlock(); } } } } public class PrinterB implements Runnable{ @Override public void run() { for (int i = 1; i <= 5; i++) { lock.lock(); try { while(cur_name != "B"){ try { conditionB.await(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("第"+i+"次打印"+cur_name); cur_name = "C"; conditionC.signal(); }catch (Exception e){ }finally { lock.unlock(); } } } } public class PrinterC implements Runnable{ @Override public void run() { for (int i = 1; i <= 5; i++) { lock.lock(); try { while(cur_name != "C"){ try { conditionC.await(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("第"+i+"次打印"+cur_name); cur_name = "A"; conditionA.signal(); }catch (Exception e){ }finally { lock.unlock(); } } } } }