線程通信兩個例子

線程通信有三種方式:

(1)synchronized+wait+notify等待喚醒方式

(2)Condition.await()方法

(3)阻塞隊列

下面根據兩道面試題分別實現線程之間的通信

(1)搜狐暢遊筆試題,以第一種方式實現

創建兩個線程,其中一個輸出1-52,另外一個輸出A-Z。輸出格式要求:12A 34B 56C 78D 依次類推

package com.interview.main;

//創建兩個線程,其中一個輸出1-52,另外一個輸出A-Z。輸出格式要求:12A 34B 56C 78D 依次類推
public class Main {
	
	private static final Object lock = new Object();
	
	public static void main(String[] args) {
		PrintNumber pn = new PrintNumber(lock);
		PrintChar pc = new PrintChar(lock);
		Thread t1 = new Thread(pn);
		Thread t2 = new Thread(pc);
		t1.start();
		t2.start();
	}

}

class PrintNumber implements Runnable {

	private Object lock;

	PrintNumber(Object lock) {
		this.lock = lock;
	}

	@Override
	public void run() {
		synchronized (lock) {
			for (int i = 1; i <= 52; i++) {
				System.out.print(i);
				if (i % 2 == 0) {// 線程暫停
					// 喚醒其他線程
					lock.notifyAll();
					try {
						lock.wait();
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}
		}
	}

}

class PrintChar implements Runnable {

	private Object lock;

	PrintChar(Object lock) {
		this.lock = lock;
	}

	@Override
	public void run() {
		synchronized (lock) {
			for (int i = 0; i < 26; i++) {
				char ch = (char) (i + 65);
				if (ch != 'Z') {
					System.out.print(ch + " ");
					// 喚醒其他線程
					lock.notifyAll();
					// 線程暫停
					try {
						lock.wait();
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}else {
					// 喚醒其他線程
					lock.notifyAll();
					System.out.print(ch);
				}
				

			}
		}

	}

}

(2)三個線程輪流執行順序打印ABC,依次是ABCABCABC......

使用ReentantLock+Condition

package com.interview.main;

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

//三個線程輪流執行順序打印ABC,依次是ABCABCABC......
public class Main {

	public static void main(String[] args) {
		printABC print = new printABC();
		new Thread(new Runnable() {
			@Override
			public void run() {
				print.PrintA();
			}
		}).start();
		new Thread(new Runnable() {
			@Override
			public void run() {
				print.PrintB();
			}
		}).start();
		new Thread(new Runnable() {
			@Override
			public void run() {
				print.PrintC();
			}
		}).start();
	}

}

class printABC {
	private static final Lock lock = new ReentrantLock();
	private Condition lockA = lock.newCondition();
	private Condition lockB = lock.newCondition();
	private Condition lockC = lock.newCondition();

	int flg = 0;// 用於切換

	public void PrintA() {
		lock.lock();
		try {
			while (true) {
				while (flg != 0) {// 不輸出
					lockA.await();
				} // 輸出
				System.out.print("A");
				flg = 1;
				lockB.signal();
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			lock.unlock();
		}
	}

	public void PrintB() {
		lock.lock();
		try {
			while (true) {
				while (flg != 1) {// 不輸出
					lockB.await();
				} // 輸出
				System.out.print("B");
				flg = 2;
				lockC.signal();
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			lock.unlock();
		}
	}

	public void PrintC() {
		lock.lock();
		try {
			while (true) {
				while (flg != 2) {// 不輸出
					lockC.await();
				} // 輸出
				System.out.print("C");
				Thread.sleep(1000);
				flg = 0;
				lockA.signal();
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			lock.unlock();
		}
	}
}

 

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