多线程通讯

生产者/消费者模式是一个经典的线程同步以及通讯的模型。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

相关文章
相关标签/搜索