多線程通訊

生產者/消費者模式是一個經典的線程同步以及通訊的模型。java

假設有這樣一種狀況,有一個盤子,盤子裏只能放一個雞蛋,A線程專門往盤子裏放雞蛋,若是盤子裏有雞蛋,則一直等到盤子裏沒雞蛋,B線程專門從盤子裏取雞蛋,若是盤子裏沒雞蛋,則一直等到盤子裏有雞蛋。這裏盤子是一個互斥區,每次放雞蛋是互斥的,每次取雞蛋也是互斥的,A線程放雞蛋,若是這時B線程要取雞蛋,因爲A沒有釋放鎖,B線程處於等待狀態,進入阻塞隊列,放雞蛋以後,要通知B線程取雞蛋,B線程進入就緒隊列,反過來,B線程取雞蛋,若是A線程要放雞蛋,因爲B線程沒有釋放鎖,A線程處於等待狀態,進入阻塞隊列,取雞蛋以後,要通知A線程放雞蛋,A線程進入就緒隊列。咱們但願當盤子裏有雞蛋時,A線程阻塞,B線程就緒,盤子裏沒雞蛋時,A線程就緒,B線程阻塞面試

package org.thread;

import java.util.ArrayList;
import java.util.List;

public class Plate {

	List<Object> eggs = new ArrayList<Object>();

	public synchronized Object getEgg() {

		while (eggs.size() == 0) {

			try {
				wait();//線程等待
			} catch (Exception e) {
			}
		}

		Object egg = eggs.get(0);
		eggs.clear();

		notify();//喚醒線程
		System.out.println("拿到雞蛋");
		return egg;
	}

	public synchronized void putEgg(Object egg) {
		while (eggs.size() > 0) {
			try {
				wait();
			} catch (Exception e) {
			}

		}

		eggs.add(egg);
		notify();
		System.out.println("放置雞蛋");
		
	}

}
package org.thread;

public class PlateThread {
	public static void main(String[] args) {

		final Plate plate = new Plate();
		
		Runnable runnable1 = new Runnable() {

			@Override
			public void run() {
				plate.getEgg();

			}
		};

		Runnable runnable2 = new Runnable() {

			@Override
			public void run() {

				plate.putEgg(new Object());

			}
		};
		
		for(int i =0;i<100;i++){
			
			new Thread(runnable1).start();
			new Thread(runnable2).start();
			
		}
		

	}

}
放置雞蛋
拿到雞蛋
放置雞蛋
拿到雞蛋
放置雞蛋
拿到雞蛋
放置雞蛋
拿到雞蛋
放置雞蛋
拿到雞蛋
放置雞蛋
拿到雞蛋

前段時間看了張孝祥老師線程的視頻,講述了一個其學員的面試題,也是線程通訊的,在此也分享一下。ide

題目:子線程循環10次,主線程循環100次,如此循環100次,好像是空中網的筆試題。oop

package org.thread;

public class HongWeb {

	// 1的話就是子循環
	// 0的話就是父循環
	private int isLoop = 1;

	public synchronized void parentLoop(String pool) {

		while (isLoop==1) {

			try {
				wait();
			} catch (Exception e) {

			}
		}

		for (int i = 0; i < 20; i++) {
			System.out.println(i + "=============" + pool);

		}
		isLoop = 1;
		notify();
	}

	public synchronized void childLoop(String pool) {

		while (isLoop==0) {

			try {
				wait();
			} catch (Exception e) {

			}
		}

		for (int i = 0; i < 10; i++) {
			System.out.println(i + "=============" + pool);

		}
		isLoop = 0;
		notify();
	}

}

家注意到沒有,在調用wait方法時,都是用while判斷條件的,而不是if,在wait方法說明中,也推薦使用while,由於在某些特定的狀況下,線程有可能被假喚醒,使用while會循環檢測更穩妥spa

相關文章
相關標籤/搜索