多线程中的wait,notify理解

一:概念性

1.wait()和notify()方法必须放在synchronized块中执行,否则没有意义意味着调用wait()和notify方法必须获得锁的控制权。

2.wait()和sleep()的区别为线程调用wait()方法会将锁释放掉,运行别的线程占有锁,自己进入等待队列。

   而sleep()只是暂时休眠,不会将手里的锁释放掉

3.notif方法会唤醒等待队列中的第一个线程,不会通知优先级高的。被唤醒的进程与其他线程平等竞争cpu资源

二:实例分析

package thread;

class Res{
    public boolean flag = true;
    public String name;
    
}

class inputThread extends Thread{
     public Res res;
     public inputThread(Res res) {
        this.res=res;
    }
    @Override
    public  void run() {
      System.out.println("我是写");
      int count=0; 
      while (true) {
          synchronized (res) {
               if (res.flag) {
              try {
                res.wait();  
              	} catch (InterruptedException e) {
                e.printStackTrace();
              	}
               }
                if (count==0) {
                	System.out.println("写入lucy");
                    res.name="lucy";   
                }else {
                	System.out.println("写入jack");
                    res.name="Jack";
                }
                count =(count+1)%2;
                res.flag=true;  
                res.notify();
        }
    }
    }
}

class readThread extends Thread{
    public Res res;
    public readThread(Res res) {
        this.res=res;
    }
    
    @Override
    public void run() {
        while (true) {    
        synchronized (res) {
               if(!res.flag){
                 try {
                    res.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }    
               }
               System.out.println("读"+res.name);

               res.flag=false;
               res.notify();
               
            }
        }        
    }
}

public class ConmunicatThreadTest {
    //开启两个线程  下面的线程 主线程 还有这俩用户线程 cpu随机的

    public static void main(String[] args) {
        Res res = new Res();
    inputThread inputThread = new inputThread(res);
    readThread  readThread = new readThread(res);
    inputThread.start();
    readThread.start();
    
    }  
       
    
}

  

1.初始值flag=true,写进程抢到锁,开始进入synchronized 代码块,因为此时flag为true,执行wait()方法,释放手中的锁,这时候写进程抢到锁因为此时flag=true,所以不执行wait()直接开始读。。。而此时因为就没有执行写入操作就释放了锁,所以自然也就取不到值所以读为null

2.执行完读取操作后继续顺序执行 res.flag=false;res.notify();因为这是个while循环所以会继续执行while中的代码块,而此时flag状态为flase就会进入写入操作模块,将数据写入后,执行  res.flag=true;  res.notify();再次进入循环语句时,执行wait(),释放手中的锁,唤醒读线程,

3.读线程拿到cpu资源,因为此时flag=true.,所以讲内容输出来,继续执行以上操作不断写入。。读取 写入。。。读取

三.wait释放锁,使用notify只是把它唤醒,可以和其他线程公平抢占资源。但是他不是一定会抢到。举个栗子

package thread;

public class RunA  implements Runnable{

	private Object lock;

	public RunA(Object lock) {
		this.lock = lock;
	}
	@Override
	public void run() {
		// TODO Auto-generated method stub
		synchronized (lock){
			  try  {
				   System.out.println("A begin");
				  // lock.wait(); // 永远等待着,不会执行下去
				   lock.wait(2000);// 等待了2秒之后,继续执行下去
				   System.out.println("A end");
			  } catch (InterruptedException e) {
				  e.printStackTrace();
			  }
		  }


	}
 
}
package thread;

public class RunB implements Runnable {
	private Object lock;

	public RunB(Object lock) {
		this.lock = lock;
	}

	@Override
	public void run() {
		// TODO Auto-generated method stub
		synchronized (lock) {
			System.out.println("b come");
			while (true) {
			}
		}
	}
	

}
package thread;

public class TestRunAandB {
	public static void main(String args[]) throws InterruptedException{
		Object lock = new Object();
		Thread threadA = new Thread(new RunA(lock));
		threadA.start();
		/*threadA.wait();
		Thread.sleep(1000);*/
		Thread.sleep(1000);
		Thread threadB = new Thread(new RunB(lock));
		threadB.start();	
	}
	

}

A线程抢到资源后,先输出A begin 等待2S后,A线程被唤醒,可是没有抢到锁所以没有输出A end;

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值