【java学习—十五】线程的通信(6)


1. 线程通信

wait()notify()notifyAll()

    ①wait():令当前线程挂起并放弃 CPU 、同步资源,使别的线程可访问并修改共享资源,而当前线程排队等候再次对资源的访问
    ②notify():唤醒正在排队等待同步资源的线程中优先级最高者结束等待
    ③notifyAll():唤醒正在排队等待资源的所有线程结束等待 .

    注意:Java.lang.Object 提供的这三个方法只有在 synchronized 方法synchronized 代码块中才能使用,否则会报 java.lang.IllegalMonitorStateException 异常(这三种方法只能在有同步锁的方法或者代码块中)

1.1. wait() 方法:

在当前线程中调用方法: 对象名.wait()

    功能:使当前线程进入等待(某对象)状态 ,直到另一线程对该对象发出 notify ( 或 notifyAll) 为止。

    调用方法的必要条件:当前线程必须具有对该对象的监控权(加锁)

    调用此方法后,当前线程将释放对象监控权 ,然后进入等待
    在当前线程被 notify 后,要重新获得监控权,然后从断点处继续代码的执行。

1.2. notify()/notifyAll() 方法

在当前线程中调用方法: 对象名.notify()

    功能:唤醒等待该对象监控权的一个线程。

    调用方法的必要条件:当前线程必须具有对该对象的监控权(加锁)


举例:

package day15;

public class Test2 {
	public static void main(String[] args) {
		
		//定义账户对象
		Account a = new Account();
		
		//多线程对象
		User u_weixin = new User(a, 2000);
		User u_zhifubao = new User(a, 2000);
		
		Thread weixin = new Thread(u_weixin, "微信");
		Thread zhifubao = new Thread(u_zhifubao, "支付宝");
		
		weixin.start();
		zhifubao.start();
	}
}

class Account{
	public static int money = 3000;//全局变量,所有操作共享这个变量
	
	/**
	 * synchronized修饰代码块,想要根据不同的对象有不同的锁
	 * synchronized(a)这个小括号中传入不同的对象就是不同的锁
	 * @param m
	 */
	public void drawing5(int m, Account a) {
		
		synchronized(a) {//表示通过方法的参数传递进来的对象的代码块被加了synchronized同步锁
			//不同的对象就有不同的同步锁
			String name = Thread.currentThread().getName();
			
			//如果是微信操作,先不执行,等待支付宝操作,支付宝操作完,微信再继续操作
			if(name.equals("微信")) {
				try {
					a.wait();//当前的线程进入等待的阻塞状态
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
			
			if(money < m) {
				System.out.println(name + "操作,账户金额不足:" + money);
			}else {
				System.out.println(name + "操作,账户原有金额:" + money);
				System.out.println(name + "操作,取款金额:" + m);
				
				money = money - m;
				
				System.out.println(name + "操作,取款后的余额:" + money);
			}
			
			if(name.equals("支付宝")) {
				try {
					a.notify();//唤醒当前优先级最高的线程,进入就绪状态
					//a.notifyAll();//唤醒当前所有的线程,进入就绪状态(效果和notifyAll()一样)
				} catch (Exception e) {
					e.printStackTrace();
				}
				
			}
		}
	}
	
	
	
}

class User implements Runnable{
	
	Account account;
	int money;
	
	public User(Account account, int money) {
		this.account = account;
		this.money = money;
	}
	
	@Override
	public void run() {
		
		account.drawing5(money, account);		
	}
}

运行结果:(先执行支付宝的线程,再执行微信的线程)

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Cpdr

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值