• 线程同步案例


    线程同步案例:

     1 package com.iotek.synchronizedtest;
     2 
     3 public class BankDemo {
     4 
     5     /** 线程同步案例
     6      * 对于线程同步,在java代码中需要完成2个操作:
     7      * (1)把竞争访问的资源标识为private
     8      * (2)同步哪些访问资源的代码,使用synchronized关键字来修饰方法或代码块
     9      * 当synchronized方法执行完成或发生异常时,会自动释放锁
    10      * 案例:某银行卡账号上有500元现金,一个人拿着存折去柜台取钱,
    11      * 同时另一个人拿着卡去ATM上取钱,各自取400元。现要求取钱的过程中不能
    12      * 出现资源竞争:比如400元被取出2次,银行的账目不能小于0等
    13      * 
    14      * @param args
    15      */
    16     public static void main(String[] args) {
    17         Bank bank = new Bank();
    18         BankTherad p1 = new BankTherad(bank);
    19         p1.start(); // 模拟柜台取钱
    20         BankTherad p2 = new BankTherad(bank);
    21         p2.start(); // 模拟ATM取钱,与模拟柜台取钱,是2个线程,竞争同一个资源:账户的余额
    22 
    23     }
    24 
    25 }
    26 
    27 class BankTherad extends Thread {
    28     private Bank bank = null; // 声明一个银行对象的引用
    29 
    30     public BankTherad(Bank bank) {
    31         this.bank = bank;
    32     }
    33 
    34     public void run() {
    35         System.out.println("取钱:" + bank.getMoney(400));
    36     }
    37 }
    38 
    39 class Bank {
    40     private int money = 500; // 银行账户里的钱是一种竞争资源,设置为私有属性
    41     private Object obj = new Object();
    42     
    43     /*
    44      * synchronized关键字声明当前方法是同步方法,当一个线程去调用同步方法时,
    45      * 这个线程就获取了当前对象的锁.获取当前对象锁的线程就去执行同步方法里的语句
    46      * 其他的线程当调用同步方法时,只能等待,因为无法获取对象的锁,这个锁已被第一个 线程持有, 只有第一个线程释放对象的锁,方可进入
    47      * 同步方法的作用就是确保方法里的代码同时只能有一个线程来访问,当同步方法运行完毕, 其他线程才能访问
    48      */
    49     /*
    50      * public synchronized int getMoney(int number) { if (number < 0) { return
    51      * -1; } else if (money < 0) { return -2; } else if (number - money > 0) {
    52      * return -3; // 取钱数目大于银行卡账户余额 } else { // 除此之外,都是正常状态 try {
    53      * Thread.sleep(1000); } catch (InterruptedException e) {
    54      * e.printStackTrace(); } // 休眠1秒钟,模拟取钱的时间 money -= number; // 取钱后的账户余额
    55      * System.out.println("余额:" + money); } return number; }
    56      */
    57     // 取钱的方法,返回取钱的数目
    58     public int getMoney(int number) { 
    59         //使用同步代码块: synchronized (this) { }  this代表获取的是当前对象的锁 
    60         synchronized (obj) {  //此处获取任何对象的锁都是可以的
    61             //this代表当前对象
    62             if (number < 0) {//取钱数目不能小于0
    63                 return -1;
    64             } else if (money < 0) {//银行账户余额不能小于0
    65                 return -2;
    66             } else if (number - money > 0) {
    67                 return -3; // 取钱数目大于银行卡账户余额
    68             } else {
    69                 // 除此之外,都是正常状态
    70                 try {
    71                     Thread.sleep(1000);
    72                 } catch (InterruptedException e) {
    73                     e.printStackTrace();
    74                 } // 休眠1秒钟,模拟取钱的时间
    75                 money -= number; // 取钱后的账户余额
    76                 System.out.println("余额:" + money);
    77             }
    78         }
    79         return number;
    80     }
    81 
    82 }
  • 相关阅读:
    Jqeury ajax 调用C#的后台程序
    电商设计1
    智能分类
    网络爬虫框架Webmagic
    Spring Cloud 微服务架构解决方案
    网站流量日志数据分析系统1
    Shell 编程
    Zookeeper
    网站流量日志数据自定义采集
    分库分表的面试题5
  • 原文地址:https://www.cnblogs.com/enjoyjava/p/8192666.html
Copyright © 2020-2023  润新知