(三十一)java多线程二

   因为线程在执行的过程中具有一定的不确定性,在并发的时候就会出现安全问题,因此一般需要采取一定的措施来保证线程的安全,同步代码块就是其中一种方式。

   以下是模拟银行取钱的多线程小例子,两个都能确保安全,但是有一种却更好一些。

例1:

packagedemo1;

/**

 *
模拟两个人同时取一个账户的钱,必须只能有一个人能取成功

 *@authortuzongxun

 *

 */

publicclass ThreadTest6 {

  publicstaticvoidmain(String[]args)
{

    // 创建一个用户账户

   Account account = newAccount("tu", 1000);

    // 创建两个线程模拟取钱

   GetMoney get1 = newGetMoney("甲", account,
600);

   GetMoney get2 = newGetMoney("乙", account,
500);

    // 启动线程

   get1.start();

   get2.start();

  }

}

 

 

/**

 * 模拟账户

 * @authortuzongxun

 *

 */

class Account {

  /**

   * 账户名

   */

  private StringaccountNum;

  /**

   * 账户余额

   */

  private Doublemoney;

 

  publicAccount(String accountNum,double money) {

    this.accountNum = accountNum;

    this.money = money;

  }

 

  public StringgetAccountNum() {

    returnaccountNum;

  }

 

  publicvoid
setAccountNum(StringaccountNum) {

    this.accountNum = accountNum;

  }

 

  public DoublegetMoney() {

    returnmoney;

  }

 

  publicvoid
setMoney(Double money) {

    this.money = money;

  }

}

 

 

classGetMoneyextends
Thread {

  privatefinal
double
num;

  privatefinal Account
account;

 

  publicGetMoney(String name,Account account,
double num) {

    super(name);

    this.num = num;

    this.account = account;

  }

 

  @Override

  publicvoid
run() {

    /**

     * 这里锁住了整个用户对象,所以先开始的线程会锁定对象,另一个不能获得对象,无法结束

     * 只有当操作账户的线程结束后,另一个线程才能结束

     */

    synchronized (account) {

      if (account.getMoney() >num) {

       account.setMoney(account.getMoney() -num);

        System.out.println("用户(
" + this.getName()
+ " )取钱成功,取了("
+ account.getAccountNum()

           + ")的账户:" +num
+ "元");

        System.out.println("账户余额:"
+ account.getMoney() +"元");

      }else {

        System.out.println("用户(
" + this.getName()
+ " )取钱失败");

        System.out.println("账户余额:"
+ account.getMoney() +"元");

      }

    }

  }

}

 

例2:

packagedemo1;

/**

 * 模拟两个人同时取一个账户的钱,必须只能有一个人能取成功

 * @authortuzongxun

 *

 */

publicclass ThreadTest7 {

  publicstaticvoidmain(String[]
args) {

   Account1 account = newAccount1("tu", 1000);

    newGetMoney1("甲", account, 600).start();

    newGetMoney1("乙", account, 500).start();

  }

}

 

/**

 * 模拟账户

 * @authortuzongxun

 *

 */

class Account1 {

  private StringaccountName;

  privatedouble
balance;

 

  publicAccount1(StringaccountName,
double balance) {

    this.accountName = accountName;

    this.balance = balance;

  }

 

  public StringgetAccountName() {

    returnaccountName;

  }

 

  publicvoid
setAccountName(StringaccountName) {

    this.accountName = accountName;

  }

 

  publicdouble
getBalance() {

    returnbalance;

  }

 

  publicvoid
setBalance(double balance) {

    this.balance = balance;

  }

 

  /**

   * 这里只是锁住了取钱的方法,所以有可能第一个线程运行一半时,第二个开始运行并可能先结束

   *但是就算第一个后结束,第二个线程依然取钱失败。

   *@param money

   * @return

   */

  publicsynchronized
double
getMondy(double money) {

    if (balance > money) {

      balance -= money;

      return 1;

    } else {

      return -1;

    }

  }

};

 

classGetMoney1extends
Thread {

  privatefinal Account1
account;

  privatefinal
double
money;

 

  publicGetMoney1(String name,Account1 account,
double money) {

    super(name);

    this.account = account;

    this.money = money;

  }

  @Override

  publicvoid
run() {

    double getMoney =account.getMondy(money);

    if (getMoney > 0){

      System.out.println(this.getName()
+ "取款成功,取了"
+ account.getAccountName() +"账户:"
+ money

         + "元");

      System.out.println("账户余额:"
+ account.getBalance());

    } else {

      System.out.println(this.getName()
+ "取款失败");

      System.out.println("账户余额:"
+ account.getBalance());

    }

  }

}

时间: 2024-09-17 16:13:48

(三十一)java多线程二的相关文章

求助,java多线程的问题,synchronized关键字不起作用

问题描述 求助,java多线程的问题,synchronized关键字不起作用 public class VoTest { private int num=1; private void increase(){ ** synchronized (this){ this.num++; }** } private int read(){ return this.num; } public static void main(String[] args) { final VoTest test=new V

超详细的Java多线程教程

<一>概述.定义任务 一.概述 为什么使用线程?从c开始,任何一门高级语言的默认执行顺序是"按照编写的代码的顺序执行",日常开发过程中写的业务逻辑,但凡不涉及并发的,都是让一个任务顺序执行以确保得到想要的结果.但是,当你的任务需要处理的业务比较多时,且这些业务前后之间没有依赖(比如, a执行的过程中b也可以执行,b没有必要必须等待a执行完毕再去执行),那么此时,我们可以将一个任务拆分成多个小任务. 例如,任务a负责接收键盘的输入,b负责将一些参数及计算提前做好(假设计算量比

JAVA多线程(三个猴子分桃)操作,为什么总是出现一个线程,求大神!

问题描述 JAVA多线程(三个猴子分桃)操作,为什么总是出现一个线程,求大神! public class ThreadDemo { int mutex = 100; boolean isRun = true; int i = 0; public static void main(String[] args) { Monkey m = new ThreadDemo().new Monkey(); new Thread(m, "1").start(); new Thread(m, &quo

Java 多线程实例详解(三)_java

本文主要接着前面多线程的两篇文章总结Java多线程中的线程安全问题. 一.一个典型的Java线程安全例子 public class ThreadTest { public static void main(String[] args) { Account account = new Account("123456", 1000); DrawMoneyRunnable drawMoneyRunnable = new DrawMoneyRunnable(account, 700); Thr

Java 多线程实例详解(二)_java

本文承接上一篇文章<Java多线程实例详解(一)>. 四.Java多线程的阻塞状态与线程控制 上文已经提到Java阻塞的几种具体类型.下面分别看下引起Java线程阻塞的主要方法. 1.join() join -- 让一个线程等待另一个线程完成才继续执行.如A线程线程执行体中调用B线程的join()方法,则A线程被阻塞,知道B线程执行完为止,A才能得以继续执行. public class ThreadTest { public static void main(String[] args) {

JAVA之旅(三十一)——JAVA的图形化界面,GUI布局,Frame,GUI事件监听机制,Action事件,鼠标事件

JAVA之旅(三十一)--JAVA的图形化界面,GUI布局,Frame,GUI事件监听机制,Action事件,鼠标事件 有段时间没有更新JAVA了,我们今天来说一下JAVA中的图形化界面,也就是GUI 一.GUI的概述 GUI全称叫做Graphical User Intergace(图形用户接口),用图形的方式,来显示计算机操作的界面,这样更加方便直观,与用户交互 说道交互,其实系统跟用户有两种交互,一种是GUI,一种叫做CLI,也就是命令行,全称叫做Command User Intergace

Java多线程知识小抄集(三)

本文主要整理博主遇到的Java多线程的相关知识点,适合速记,故命名为"小抄集".本文没有特别重点,每一项针对一个多线程知识做一个概要性总结,也有一些会带一点例子,习题方便理解和记忆. 51. SimpleDateFormat非线程安全 当多个线程共享一个SimpleDateFormat实例的时候,就会出现难以预料的异常. 主要原因是parse()方法使用calendar来生成返回的Date实例,而每次parse之前,都会把calendar里的相关属性清除掉.问题是这个calendar是

Java多线程知识小抄集(二)

本文主要整理博主遇到的Java多线程的相关知识点,适合速记,故命名为"小抄集".本文没有特别重点,每一项针对一个多线程知识做一个概要性总结,也有一些会带一点例子,习题方便理解和记忆. 27. ConcurrentHashMap ConcurrentHashMap是线程安全的HashMap,内部采用分段锁来实现,默认初始容量为16,装载因子为0.75f,分段16,每个段的HashEntry<K,V>[]大小为2.键值都不能为null.每次扩容为原来容量的2倍,Concurre

JAVA多线程实现的三种方式

JAVA多线程实现 JAVA多线程实现方式主要有三种:继承Thread类.实现Runnable接口.使用ExecutorService.Callable.Future实现有返回结果的多线程.其中前两种方式线程执行完后都没有返回值,只有最后一种是带返回值的. 前两种大家应该都熟悉,第三种不太常用,但有时面试时会问到所以我在这里写下. 继承Thread类实现多线程 继承Thread类的方法尽管被我列为一种多线程实现方式,但Thread本质上也是实现了Runnable接口的一个实例,它代表一个线程的实