在该示例代码中,TestAccount类是测试类,主要实现创建帐户Account类的对象,以及启动学生线程StudentThread和启动家长线程GenearchThread。在StudentThread线程中,执行的功能是每隔2秒中取一次钱,每次取50元。在GenearchThread线程中,执行的功能是每隔12秒存一次钱,每次存200。这样存款和取款之间不仅时间间隔存在差异,而且数量上也会出现交叉。而该示例中,最核心的代码是Account类的实现。

在Account类中,实现了同步控制功能,在该类中包含一个关键的属性money,该属性的作用是存储帐户金额。在介绍该类的实现前,首先介绍一下两个同步方法——wait和notify方法的使用,这两个方法都是Object类中的方法,也就是说每个类都包含这两个方法,换句话说,就是Java天生就支持同步处理。这两个方法都只能在synchronized修饰的方法或语句块内部采用被调用。其中wait方法的作用是使调用该方法的线程休眠,也就是使该线程退出CPU的等待队列,处于冬眠状态,不执行动作,也不占用CPU排队的时间,notify方法的作用是唤醒一个任意该对象的线程,该线程当前处于休眠状态,至于唤醒的具体是那个则不保证。在Account类中,被StudentThread调用的getMoney方法的功能是判断当前金额是否是0,如果是则使StudentThread线程处于休眠状态,如果金额不是0,则取出50元,同时唤醒使用该帐户对象的其它一个线程,而被GenearchThread线程调用的saveMoney方法的功能是判断当前是否不为0,如果是则使GenearchThread线程处于休眠状态,如果金额是0,则存入200元,同时唤醒使用该帐户对象的其它一个线程。

如果还是不清楚,那就结合前面的程序执行结果来解释一下程序执行的过程:在程序开始执行时,学生线程和家长线程都启动起来,所以输出“准备取钱”和“准备存钱”,然后学生线程按照该线程run方法的逻辑执行,先延迟2秒,然后调用帐户对象a中的getMoney方法,但是由于初始情况下帐户对象a中的money数值为0,所以学生线程就休眠了。在学生线程执行的同时,家长线程也按照该线程的run方法的逻辑执行,先延迟12秒,然后调用帐户对象a中的saveMoney方法,由于帐户a对象中的money为零,条件不成立,所以执行存入200元,同时唤醒线程,由于使用对象a的线程现在只有学生线程,所以学生线程被唤醒,开始执行逻辑,取出50元,然后唤醒线程,由于当前没有线程处于休眠状态,所以没有线程被唤醒。同时家长线程继续执行,先延迟12秒,这个时候学生线程执行了4次,耗时4X2秒=8秒,就取光了帐户中的钱,接着由于帐户为0则学生线程又休眠了,一直到家长线程延迟12秒结束以后,判断帐户为0,又存入了200元,程序继续执行下去。

在解决多线程问题是,互斥和同步都是解决问题的思路,如果需要形象的比较这两种方式的区别的话,就看一下下面的示例。一个比较忙的老总,桌子上有2部电话,在一部处于通话状态时,另一部响了,老总拿其这部电话说我在接电话,你等一下,而没有挂电话,这种处理的方式就是互斥。而如果老总拿其另一部电话说,我在接电话,等会我打给你,然后挂了电话,这种处理的方式就是同步。两者相比,互斥明显占用系统资源(浪费电话费,浪费别人的时间),而同步则是一种更加好的解决问题的思路。

JAVA多线程----用--取钱问题2的更多相关文章

  1. JAVA多线程----用--取钱问题1

    “生产者-消费者”模型,也就是生产者线程只负责生产,消费者线程只负责消费,在消费者发现无内容可消费时则睡觉.下面举一个比较实际的例子——生活费问题. 生 活费问题是这样的:学生每月都需要生活费,家长一 ...

  2. Java多线程---同步与锁

    一,线程的同步是为了防止多个线程访问一个数据对象时,对数据造成的破坏. 二.同步和锁定 1.锁的原理 Java中每个对象都有一个内置锁. 当程序运行到非静态的synchronized同步方法上时,自动 ...

  3. Java多线程之使用ATM与柜台对同一账户取钱

    钱数要设置成静态的变量,两种取钱方式操作的是同一个银行账户! 废话不多说,直接上代码.注释写的都很详细!!! package com.thread.multi2; public class Bank ...

  4. 【JAVA】编程(3)---王狗蛋先生去取钱,发现余额不足 !?!?

    作业要求: 1.写一个名为Account的类模拟账户.该类的属性和方法如下所示: 该类包括的属性: ID,余额balance,年利率; 包含的方法:各属性的set和get方法.取款方法withdraw ...

  5. Java多线程 3 线程同步

    在之前,已经学习到了线程的创建和状态控制,但是每个线程之间几乎都没有什么太大的联系.可是有的时候,可能存在多个线程多同一个数据进行操作,这样,可能就会引用各种奇怪的问题.现在就来学习多线程对数据访问的 ...

  6. Java—多线程编程

    一个多线程程序包含两个或多个能并发运行的部分.程序的每一部分都称作一个线程,并且每个线程定义了一个独立的执行路径. 进程:一个进程包括由操作系统分配的内存空间,包含一个或多个线程.一个线程不能独立的存 ...

  7. java多线程基础

    多线程基础 读书练习照猫画虎 package Threadtest; import java.util.Date; import java.util.concurrent.ArrayBlockingQ ...

  8. Java总结篇系列:Java多线程(三)

    本文主要接着前面多线程的两篇文章总结Java多线程中的线程安全问题. 一.一个典型的Java线程安全例子 public class ThreadTest { public static void ma ...

  9. JAVA多线程的问题以及处理【转】

    http://www.cnblogs.com/springcsc/archive/2009/12/03/1616394.html 12.4 多线程问题及处理          多线程编程为程序开发带来 ...

随机推荐

  1. Hdu 1455

    #include <iostream> #include <cstdio> #include <cstdlib> #include <algorithm> ...

  2. valgrind的memchk和callgrind

    一.安装valgrind 安装valgrind,正常的三部曲configure/make/make install就行. 二.memchk使用 1.执行命令 [root@10g-host4 tools ...

  3. WinCE数据通讯之SqlCE数据同步篇

    上一篇总结了WinCE通过WebService进行数据通讯的交互方式,今天整理个SqlCE数据同步方式的内容.先说下软件环境:终端平台使用WinCE5.0+SqlCE2.0,服务器使用Windows ...

  4. xshell5使用ssh连接阿里云服务器

    这里有两种方式,一种是在阿里云的控制台里面进行,另一种是在Xshell里面生成密钥. 阿里云控制台密钥对 点击右上方的创建密钥对 在阿里云里面生成较为简单,点击该页面右上方的“创建密钥对”,在另一个页 ...

  5. [PostgreSql]PostgreSql创建函数及函数的执行

    1.准备好创建函数的脚本 -- FUNCTION: public.dynamic_placelist_select(integer, timestamp without time zone) -- D ...

  6. Eclipse中快速定位

    Eclipse中快速定位 选中项目,ctrl+h 一.目标 查找如下的页面属于哪个activity 二.步骤 1.查找关键字 上述页面中“点我”两个字比较显眼,我们可以去android项目中搜索出现“ ...

  7. unity屏幕坐标转世界坐标结果为(0,0,0)

    代码: wv转出来一直为(0,0,0),卡了好久,问别人说要转化的屏幕坐标Z不能为0 阿西吧!特此记录

  8. 《深入理解mybatis原理1》 MyBatis的架构设计以及实例分析

    <深入理解mybatis原理> MyBatis的架构设计以及实例分析 MyBatis是目前非常流行的ORM框架,它的功能很强大,然而其实现却比较简单.优雅.本文主要讲述MyBatis的架构 ...

  9. Lua学习笔记1,基本数据类型

    1.字符串的连接使用的是  .. ,如 print(123 .. 44) 输出 12344 print ('a' .. 'b') 输出 ab print(123 .. 44)这句的时候 .. 两边要空 ...

  10. p-value值的认识

    待续:https://www.zhihu.com/question/21429785/answer/147047565