/** * */ package com.shenli.thread.cooperation; import java.util.concurrent.atomic.AtomicInteger; /** * @author ShenLi * 要求用兩個現成交替的打印出字母A~Z * 線程協作 * * 實現:通過構造兩個線程,互相持有對方的觀察對象來完成協作: * 線程A拿到線程B的關注對象,線程B拿到線程A的觀察對象 * 在程序啓動的時候,兩個現成默認都等待對象釋放 * 由主線程首先釋放其中一個對象,之後 * 兩個對象交替執行,並交替釋放對方的關注對象, * 直到工作完成。 * */ public class ThreadCooperation extends Thread{ /** * * @param args * @throws InterruptedException */ public static void main(String[] args) throws InterruptedException { Object flag1 = new Object(); Object flag2 = new Object(); MyThread t1 = new MyThread(flag1,flag2); t1.start(); MyThread t2 = new MyThread(flag2,flag1); t2.start(); Thread.sleep(2000L); //通知其中一個線程開始工作 synchronized (flag1) { flag1.notify(); } } //定義字母的初始值 private static final AtomicInteger ai = new AtomicInteger((int)'A'); //定義字母的結束值 private static final int END = (int)'Z'; /** * 使用自定義線程實現 * @author ShenLi * */ static class MyThread extends Thread{ //定義自己的線程觀察對象 private Object self = null; //定義另一個線程的觀察對象 private Object other = null; //在構造函數裏傳入兩個現成的觀察對象 public MyThread(Object self, Object other){ this.self = self; this.other = other; } @Override public void run() { System.out.println(Thread.currentThread().getName() + " is running..."); //未打印完成前一直循環 while(ai.get() < END){ //同步自己的觀察對象 synchronized(self){ try { //等待釋放自己的觀察對象後,進行字母打印 self.wait(); System.out.println(Thread.currentThread().getName() +" "+ (char)ai.getAndIncrement()); } catch (InterruptedException e) { e.printStackTrace(); } } synchronized (other) { //自己打印完之後,通知另一個線程可以繼續打印。 other.notify(); } } } } }
程序執行後輸出:
Thread-0 is running... Thread-1 is running... Thread-0 A Thread-1 B Thread-0 C Thread-1 D Thread-0 E Thread-1 F Thread-0 G Thread-1 H Thread-0 I Thread-1 J Thread-0 K Thread-1 L Thread-0 M Thread-1 N Thread-0 O Thread-1 P Thread-0 Q Thread-1 R Thread-0 S Thread-1 T Thread-0 U Thread-1 V Thread-0 W Thread-1 X Thread-0 Y Thread-1 Z