多個線程順序進行和輪詢進行的問題

廢話不說了,晚上看到一個問題,需要ABC線程,能依次打印ABC(需要循環的)?

之前看能沒有看到它需要循環打出這些,只是覺得他要順序打出,所以就用了join 這個關鍵字做了一個demo;

package com.zeng.thread;
/**
 * 實現三個線程ABC,按照順序輸出ABC
 * 方案一
 * 
 * @author leo-zeng
 *
 */
public class Test1 {
	public static void main(String[] args) throws Exception {
		//A 線程
		Thread t1 = new Thread(new Runnable() {
			
			public void run() {
				System.out.println("A");
				try {
					Thread.sleep(100);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		},"A");
		
		//b線程
		Thread t2 = new Thread(new Runnable() {

			public void run() {
				System.out.println("B");
				try {
					Thread.sleep(100);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}, "B");
		
		//C 線程
		Thread t3 = new Thread(new Runnable() {
			
			public void run() {
				System.out.println("C");
				try {
					Thread.sleep(100);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		},"C");
		
		t1.start();
		t1.join();
		t2.start();
		t2.join();
		t3.start();
	}
}
打印出的結果是ABC

後來仔細一看,不滿足,問題的條件是需要循環打出ABC,所以用join 是不滿足的,這會只能用到lock,通過condition來滿足這個需求;下面也寫了這個demo,

demo比較簡單,通過一個reentrantLock 和 condition 的await 和single 方法,進行線程間的輪詢,來達到結果;看下demo吧!

package com.zeng.thread;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

/**
 * Abc 三個線程分別輸出循環輸出 abc 用reentrantLock
 * 
 * @author leo-zeng
 * 
 */
public class ReentrantLockDemo {
	public static void main(String[] args) {
		// 重入鎖
		final ReentrantLock rLock = new ReentrantLock();
		// 三個condition
		final Condition aCon = rLock.newCondition();
		final Condition bCon = rLock.newCondition();
		final Condition cCon = rLock.newCondition();
		//線程a
		Thread a = new Thread(new Runnable() {

			public void run() {
				try {
					//先給第一個線程加上一段時間,給bc 線程 加鎖 ,加信號
					Thread.sleep(500);
					} catch (InterruptedException e2) {
					// TODO Auto-generated catch block
					e2.printStackTrace();
					}
				for (int i = 0; i < 3; i++) {
					try {
						// 加上鎖
						rLock.lock();
						System.out.println("A");
						Thread.sleep(1000);
						// 打印完A 之後 關閉a 給b 信號
						bCon.signal();
						//等待一個a給的信號
						try {
							aCon.await();
						} catch (InterruptedException e1) {
							e1.printStackTrace();
						}
					} catch (InterruptedException e) {
						e.printStackTrace();
					} finally {
						// 解鎖
						rLock.unlock();
					}
				}
			}
		}, "A");
		//線程b
		Thread b = new Thread(new Runnable() {

			public void run() {
				for (int i = 0; i < 3; i++) {
					try {
						// 加上鎖
						rLock.lock();
						try {
							//等待bcon
							bCon.await();
						} catch (InterruptedException e2) {
							e2.printStackTrace();
						}
						System.out.println("B");
						Thread.sleep(1000);
						// 打印完b 之後  給c 信號
						cCon.signal();
					} catch (InterruptedException e) {
						e.printStackTrace();
					} finally {
						// 解鎖
						rLock.unlock();
					}
				}
			}
		}, "B");
		//線程c
		Thread c = new Thread(new Runnable() {

			public void run() {
				for (int i = 0; i <3; i++) {
					try {
						// 加上鎖
						rLock.lock();
						try {
							//等待ccon
							cCon.await();
						} catch (InterruptedException e2) {
							e2.printStackTrace();
						}
						System.out.println("C");
						Thread.sleep(1000);
						// 打印完c 之後  給a 信號
						aCon.signal();
					} catch (InterruptedException e) {
						e.printStackTrace();
					} finally {
						// 解鎖
						rLock.unlock();
					}
				}
			}
		}, "C");
		//a b c 線程
		a.start();
		b.start();
		c.start();
		Thread.yield();
	}
}
這裏就不重點介紹ReentrantLock鎖了;下次再和synchronized 一起對比介紹!


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章