Java多线程协调控制之wait&notifyAll

最近在复习Java基础,看到多线程这块顺便写写多线程的协调控制程序。

需求:假设系统中有两个线程分别代表取款者和存款者,现在系统的要求是存款者和取款者不断的重复存、取款操作,

并且要求每当有存款者将钱存入指定账户中时,取款者就立即取出这笔钱,即不允许存款者连续两次存钱,也不允许

取款者两次取钱。

下面代码实现:

1.首先是账户Account类;

package com.xjtu.cruise.soft.thread;

public class Account {

	/**
	 * @author Cruise
	 * @param args
	 */
	private String accountNo;
	//标识账户是否还有存款的
	private boolean flag = false;
	private double balance;

	public Account(){}
	public Account(String accountNo, double balance) {
		this.accountNo = accountNo;
		this.balance = balance;
	}

	public double getBalance(){
		return balance;
	}
	public synchronized void draw(double drawAmount) {
		try {
			if (!flag) {  //如果账户没钱
				wait();  //阻塞当前的方法,并释放同步锁(这里就是this,也就是调用此方法的对象)
			} else {
				System.out.println("线程:" + Thread.currentThread().getName()
						+ "取款" + drawAmount);
				balance -= drawAmount;
				System.out.println("账户余额:" + balance);
				flag = false;
				notifyAll();  //唤醒等待此同步锁的所有线程
			}
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}

	public synchronized void deposit(double depositAmount) {

		try{
			if(flag){ //如果账户有存入的钱
				wait();
			}else{
				System.out.println("线程:"+ Thread.currentThread().getName()+"存款"+depositAmount);
				balance += depositAmount;
				System.out.println("账户余额:" + balance);
				flag = true;
				notifyAll();
			}
		}catch(InterruptedException e){
			e.printStackTrace();
		}
	}

}

2.接下来是存取款线程类(DrawThread,DepositThread)

package com.xjtu.cruise.soft.thread;

public class DepositThread extends Thread {

	private Account account;
	private double depositAmount;

	public DepositThread(String name, Account account, double depositAmount) {
		super(name);
		this.account = account;
		this.depositAmount = depositAmount;
	}

	public void run(){
		for(int i=0; i<100; i++){
//			System.out.println("线程:" + Thread.currentThread().getName()+"执行存款操作。");
			account.deposit(depositAmount);
		}
	}
}
package com.xjtu.cruise.soft.thread;

public class DrawThread extends Thread {
/**
     * @author Cruise
     * @param args
     */
	private Account account;
	private double drawAmount;

	public DrawThread(String name, Account account, double drawAmount) {
		super(name);
		this.account = account;
		this.drawAmount = drawAmount;
	}

	public void run(){
		for(int i=0; i<100; i++){
//			System.out.println("线程:" + Thread.currentThread().getName()+"执行取钱操作。");
			account.draw(drawAmount);
		}
	}
}

3.奉上测试类TestDraw

package com.xjtu.cruise.soft.thread;

public class TestDraw {

	/**
	 * @author Cruise
	 * @param args
	 */
	public static void main(String[] args) {
		Account account = new Account("123", 0);
		new DrawThread("取钱者", account, 800).start();
		new DepositThread("存款者甲",account, 800).start();
		new DepositThread("存款者乙",account, 800).start();

	}

}

OK, 一个线程协调控制的Demo完成。

时间: 2024-12-25 22:19:45

Java多线程协调控制之wait&notifyAll的相关文章

java 多线程(wait/notify/notifyall)

package com.example; public class App { /* wait\notify\notifyAll 都属于object的内置方法 * wait: 持有该对象的线程把该对象的控制权交出 notify: 通知某个正在等待该对象控制权的线程可以继续运行 notifyAll: 通知所有等待该对象控制权的线程继续运行 */ public static void main(String[] args) { MyThread mt = new MyThread(); mt.sta

java基础知识回顾之java Thread类学习(七)--java多线程通信等待唤醒机制(wait和notify,notifyAll)

1.wait和notify,notifyAll: wait和notify,notifyAll是Object类方法,因为等待和唤醒必须是同一个锁,不可以对不同锁中的线程进行唤醒,而锁可以是任意对象,所以可以被任意对象调用的方法,定义在Object基类中. wait()方法:对此对象调用wait方法导致本线程放弃对象锁,让线程处于冻结状态,进入等待线程的线程池当中.wait是指已经进入同步锁的线程,让自己暂时让出同步锁,以便使其他正在等待此锁的线程可以进入同步锁并运行,只有其它线程调用notify方

java—多线程—notify/notifyAll

notify应该使用在,只有两个线程在调用类中的两个方法,并在两个方法中进行互斥操作? 博客:Java多线程学习之wait.notify/notifyAll 详解 未完待续…… 原文地址:https://www.cnblogs.com/Tpf386/p/11185067.html

Java 多线程学习笔记:wait、notify、notifyAll的阻塞和恢复

前言:昨天尝试用Java自行实现生产者消费者问题(Producer-Consumer Problem),在coding时,使用到了Condition的await和signalAll方法,然后顺便想起了wait和notify,在开发中遇到了一个问题:wait.notify等阻塞和恢复的时机分别是什么?在网上Google了很久各种博文后,发现几乎没有人提到这个点.最后在官方文档中才找到了相应的介绍. (一)准备 按照惯例应该是要先介绍一下wait.notify和notifyAll的基础知识.我找到了

Rhythmk 一步一步学 JAVA (21) JAVA 多线程

1.JAVA多线程简单示例 1.1 .Thread  集成接口 Runnable 1.2 .线程状态,可以通过  Thread.getState()获取线程状态: New (新创建) Runnable (可以运行) Blocked  (被阻塞) Waiting  (等待) Timed waiting (计时等待) Terminated  (被终止) ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27

(转载)Java多线程入门理解

转载出处http://blog.csdn.net/evankaka 写在前面的话:此文只能说是java多线程的一个入门,其实Java里头线程完全可以写一本书了,但是如果最基本的你都学掌握好,又怎么能更上一个台阶呢?如果你觉得此文很简单,那推荐你看看Java并发包的的线程池(Java并发编程与技术内幕:线程池深入理解),或者看这个专栏:Java并发编程与技术内幕.你将会对Java里头的高并发场景下的线程有更加深刻的理解. 目录(?)[-] 一扩展javalangThread类 二实现javalan

synchronized与static synchronized 的差别、synchronized在JVM底层的实现原理及Java多线程锁理解

本Blog分为例如以下部分: 第一部分:synchronized与static synchronized 的差别 第二部分:JVM底层又是怎样实现synchronized的 第三部分:Java多线程锁,源码剖析 第一部分:synchronized与static synchronized的差别 1.synchronized与static synchronized 的差别 synchronized是对类的当前实例进行加锁,防止其它线程同一时候訪问该类的该实例的全部synchronized块.注意这里

JAVA多线程和并发基础面试问答(转载)

原文链接:http://www.cnblogs.com/dolphin0520/p/3932934.html 多线程和并发问题是Java技术面试中面试官比较喜欢问的问题之一.在这里,从面试的角度列出了大部分重要的问题,但是你仍然应该牢固的掌握Java多线程基础知识来对应日后碰到的问题. Java多线程面试问题 1. 进程和线程之间有什么不同? 一个进程是一个独立(self contained)的运行环境,它可以被看作一个程序或者一个应用.而线程是在进程中执行的一个任务.Java运行环境是一个包含

JAVA多线程和并发基础面试问答

原文链接:http://ifeve.com/java-multi-threading-concurrency-interview-questions-with-answers/ 多线程和并发问题是Java技术面试中面试官比较喜欢问的问题之一.在这里,从面试的角度列出了大部分重要的问题,但是你仍然应该牢固的掌握Java多线程基础知识来对应日后碰到的问题.(校对注:非常赞同这个观点) Java多线程面试问题 1. 进程和线程之间有什么不同? 一个进程是一个独立(self contained)的运行环