2020/4/22学习笔记day45

java-day45

wait notify notifyAll 方法

wait、notify、notifyAll方法都是Object中的方法,任何对象都可以调用到这个方法。

但是只能在加锁的代码块中,使用【当做锁的对象】来调用wait、notify、notifyAll方法。其他情况,如果不是在加锁的代码块中,或者不是使用【当做锁的对象】来调用wait、notify、notifyAll方法,是会报错的。

wait方法:

当一个线程在拿到锁去执行加锁的代码的时候,如果这个线程在代码中执行了【锁对象.wait()】方法,那么这个时候,当前线程就会立马交出cpu使用权,同时释放之前拿到的锁对象,并且从运行状态直接进入到等待池中变为阻塞状态。

当一个线程由于调用了【锁对象.wait()】方法进入到等待池中变为阻塞状态的时候,可以在另一个线程中调用【锁对象.notify()】方法把这个线程叫醒,或者调用这个线程的interrupt方法把它的阻塞状态给打断,这时候在等待池中阻塞的这个线程就会进入到锁池中,并且除以处于阻塞状态,但是它会时刻监控着它需要用的锁是否可用,一旦锁对象变成可用的,那么就会从锁池中的阻塞状态进入到就绪状态。

notify():

唤醒在等待该对象同步锁的线程(只唤醒一个,如果有多个在等待),注意的是在调用此方法的时候,并不能确切的唤醒某一个等待状态的线程,而是由JVM确定唤醒哪个线程,而且不是按优先级。

调用任意对象的notify()方法则导致因调用该对象的 wait()方法而阻塞的线程中随机选择的一个解除阻塞(但要等到获得锁后才真正可执行)。

notifyAll():

唤醒所有等待的线程,注意唤醒的是notify之前wait的线程,对于notify之后的wait线程是没有效果的。

多线程例子:

public class ThreadTest7 {
	
	public static void main(String[] args) {
		
		Account account = new Account(5000);
		
		Boy boy = new Boy(account, "tom");
		
		Girl girl1 = new Girl(account, "lily1");
		Girl girl2 = new Girl(account, "lily2");
		Girl girl3 = new Girl(account, "lily3");
		
		boy.start();
		girl1.start();
		girl2.start();
		girl3.start();
		
	}
	
	
	private static class Account{
		
		private int balance;
		
		public Account(int balance) {
			this.balance = balance;
		}
		
		//存钱
		public synchronized void pos(int money) {
			
			String name = Thread.currentThread().getName();
			balance+=money;
			System.out.println(name+"刚刚向账户中存入"+money+"元,当前余额为"+balance+"元");
			
			//钱存好了,马上释放this这个锁了,这里可以叫醒其他线程,让他们从等待池进入到锁池
			//这个锁一旦释放,那么就锁池中的线程就会进入到就绪状态,争夺执行权以及获取锁对象,然后再执行代码
			this.notifyAll();
		}
		//取钱
		public synchronized void wit(int money) {
			String name = Thread.currentThread().getName();
			while(balance<money) {
				try {
					this.wait();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
			balance-=money;
			System.out.println(name+"刚刚从账户中消费"+money+"元,当前余额为"+balance+"元");
		}
		
	}
	
	
	private static class Boy extends Thread{
		private Account account;
		public Boy(Account account,String name) {
			super(name);
			this.account = account;
		}
		@Override
		public void run() {
			while(true) {
				int money = (int)(Math.random()*10000+1);
				account.pos(money);//存钱
				try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	}
	
	private static class Girl extends Thread{
		
		private Account account;
		
		public Girl(Account account,String name) {
			super(name);
			this.account = account;
		}
		
		@Override
		public void run() {
			while(true) {
				int money = (int)(Math.random()*10000+1);
				account.wit(money);
				try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
		
	}
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值