先上结论

当线程获得锁后,不论if判断还是while判断都会从wait()方法之后的代码开始执行

然后重点来了!!!

当if/while判断语句块中wait()方法之后的代码执行完后,使用if判断时,接下来会直接执行if判断语句块后的代码;而使用while判断时,会再一次从while判断开始执行。也就是说,使用if判断线程被唤醒后,不管条件是否符合都会执行if判断语句块后的代码;而使用while判断线程被唤醒后,会再一次判断是否满足进入while代码块的条件。使用if判断可能会出现条件之外的结果,使用while判断则不会出现条件之外的结果。

代码解析

上代码

package Factory;

//工厂类
public class FactoryDemo {
	//产品类
	static class Product{
		//产品数量
		int num=0;
		
		//生产产品的方法
		public synchronized void add(){
			//判断产品数量是否满足等待条件(分别使用if和while运行后对比结果)
			if(judgeNum(num,true)){
				try {
					//获取线程名并在wait方法前、后,以及判断代码块之后分别作一次输出
					System.out.println(Thread.currentThread().getName()+"wait");
					this.wait();
					System.out.println(Thread.currentThread().getName()+"结束wait");
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			num++;
			System.out.println(Thread.currentThread().getName()+"增加了一件货物,剩余:"+num);
			//唤醒等待中的线程
			this.notifyAll();
		}
		
		//消耗产品的方法
		public synchronized void del(){
			//判断产品数量是否满足等待条件(分别使用if和while运行后对比结果)
			if(judgeNum(num,false)){
				try {
					//获取线程名并在wait方法前、后,以及判断代码块之后分别作一次输出
					System.out.println(Thread.currentThread().getName()+"wait");
					this.wait();
					System.out.println(Thread.currentThread().getName()+"结束wait");
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			num--;
			System.out.println(Thread.currentThread().getName()+"减少了一件货物,剩余:"+num);
			//唤醒等待中的线程
			this.notifyAll();
		}
		
		private boolean judgeNum(int number,boolean add_del){
			//add_del如果为true,表示进入是否满足add方法的判断;如果为false,表示进入是否满足del方法的判断
			//当产品数量大于等于10时返回true,线程进入判断代码块中并调用wait方法
			if(number>=10&&add_del){
				System.out.println(Thread.currentThread().getName()+"进入判断--返回true,传入的是"+number);
				return true;
			}
			
			//当产品数量小于等于0时返回true,线程进入判断代码块中并调用wait方法
			if(num<=0&&!add_del){
				System.out.println(Thread.currentThread().getName()+"进入判断--返回true,传入的是"+number);
				return true;
			}
			
			//不满足条件则返回false
			return false;
		}
	}
	
	public static void main(String[] args) {
		//创建产品对象
		Product pd=new Product();
		
		//创建两个生产者线程A,B以及两个消费者线程C,D,分别执行20次增加/减少操作
		new Thread(()->{
			for(int i=0;i<20;i++)
				pd.add();
		},"A").start();

		new Thread(()->{
			for(int i=0;i<20;i++)
				pd.add();
		},"B").start();
		
		new Thread(()->{
			for(int i=0;i<20;i++)
				pd.del();
		},"C").start();
		
		new Thread(()->{
			for(int i=0;i<20;i++)
				pd.del();
		},"D").start();
	}
}

运行结果对比:

java while 赋值加判断 java if while_System

java while 赋值加判断 java if while_并发编程_02