zoukankan      html  css  js  c++  java
  • 同步方法跟同步方法块 synchronized

    • synchronized方法控制对象的访问,每个对象对应一把锁,每个synchronized方法都必须获得改方法的对象的锁才能执行,否则线程会阻塞,方法一旦执行,就独占这把锁,知道方法结束才释放锁,后面被阻塞的线程才能获得这个锁被执行
    • synchronized关键字可以用在方法上标识锁住this对象
    • synchronized(Obj)方法块用在方法内 Obj是被锁的对象

    代码示例1 模拟买票

     1 package 多线程练习.锁学习;
     2 
     3 public class 不安全线程买票实例 {
     4     public static void main(String[] args) {
     5         BuyTicket bt = new BuyTicket();
     6         new Thread(bt, "小明").start();
     7         new Thread(bt, "王老师").start();
     8         new Thread(bt, "黄牛党").start();
     9     }
    10 }
    11 
    12 
    13 /*
    14    模拟一个买票的线程接口实现类
    15  */
    16 class BuyTicket implements Runnable {
    17 
    18     private int ticket = 10;
    19     private Boolean flag = true;
    20 
    21     @Override
    22     public void run() {
    23         while (flag) {
    24             buy();
    25         }
    26     }
    27 
    28     /*
    29        买票方法
    30      */
    31     public synchronized void buy() {
    32         // 票卖完了
    33         if (ticket <= 0) {
    34             flag = false;
    35             return;
    36         }
    37 
    38         // 模拟延时
    39         try {
    40             Thread.sleep(100);
    41         } catch (InterruptedException e) {
    42             e.printStackTrace();
    43         }
    44 
    45         //模拟买票
    46         System.out.println(Thread.currentThread().getName() + " 买到了第 " + ticket-- + " 张表");
    47     }
    48 }
    View Code

    输出结果

    代码示例2 模拟银行取钱

     1 package 多线程练习.锁学习;
     2 
     3 import java.math.BigDecimal;
     4 
     5 /*
     6    模拟两个人同时取钱的情况
     7  */
     8 public class SafeAccount {
     9     public static void main(String[] args) {
    10         Bank bank = new Bank("12345", new BigDecimal("100"));
    11         WithDrawMoney xiaoming = new WithDrawMoney(bank, new BigDecimal("50"), "小明");
    12         WithDrawMoney xiaomingxf = new WithDrawMoney(bank, new BigDecimal("100"), "小明媳妇");
    13         xiaoming.start();
    14         xiaomingxf.start();
    15 
    16     }
    17 }
    18 
    19 
    20 /*
    21    银行类
    22  */
    23 class Bank {
    24     String cardNumer;    // 卡号
    25     BigDecimal balance;  // 余额  小tip:Java中用BigDecimal 来表示金钱类型
    26 
    27     public Bank(String cardNumer, BigDecimal balance) {
    28         this.cardNumer = cardNumer;
    29         this.balance = balance;
    30     }
    31 
    32 }
    33 
    34 class WithDrawMoney extends Thread {
    35     //  模拟正式环境全部私有
    36     Bank bank;
    37     BigDecimal nowMoney = new BigDecimal("0");   // 手里的钱
    38     BigDecimal drawMoney;  // 取走的钱
    39 
    40     // 构造方法
    41     public WithDrawMoney(Bank bank, BigDecimal drawMoney, String name) {
    42         super(name);  // 调用父类的只能用在第一行
    43         this.bank = bank;
    44         this.drawMoney = drawMoney;
    45     }
    46 
    47     @Override
    48     public void run() {
    49 
    50         /*
    51         synchronized 用在方法上面 则不需要在方法内加synchronized代码块  用在方法指定的是锁this对象 反射类。
    52         synchronized 应当需要锁住的对象
    53          */
    54         synchronized (bank) {
    55             if (bank.balance.subtract(drawMoney).compareTo(BigDecimal.ZERO) == -1) {
    56                 System.out.println(this.getName() + " 钱不够了,取钱失败");  // 线程类中this.getName() ==  Thread.currentThread.getName()
    57                 return;
    58             }
    59 
    60             try {
    61                 Thread.sleep(500);
    62             } catch (InterruptedException e) {
    63                 e.printStackTrace();
    64             }
    65 
    66             nowMoney = nowMoney.add(drawMoney);                       // 手里的钱
    67             bank.balance = (bank.balance.subtract(drawMoney));        // 卡上余额 subtract 减法  add 加法
    68             System.out.println(this.getName() + " 手里有 " + nowMoney + "钱");
    69             System.out.println("卡上余额:" + bank.balance);
    70         }
    71 
    72     }
    73 
    74 
    75 }
    View Code

    输出结果

    代码示例3 容器

     1 package 多线程练习.锁学习;
     2 
     3 import java.util.ArrayList;
     4 import java.util.List;
     5 
     6 /*
     7   synchronized(Obj) 此处的 是锁住list对象
     8   Obj又称同步监视器
     9  */
    10 public class SafeList {
    11     public static void main(String[] args) {
    12         List<String> list = new ArrayList<>();
    13 
    14         for (int i = 0; i < 10000; i++) {
    15             new Thread(() -> {
    16                 synchronized (list) {
    17                     list.add(Thread.currentThread().getName());
    18                 }
    19             }).start();
    20         }
    21 
    22         // Sleep就是为了扩大事情的发展面
    23         try {
    24             Thread.sleep(3000);
    25         } catch (InterruptedException e) {
    26             e.printStackTrace();
    27         }
    28 
    29         System.out.println("数量为:" + list.size());
    30 
    31     }
    32 }
    View Code

    输出结果

  • 相关阅读:
    如何Android Apk反编译得到Java源代码
    安卓反编译揭秘!!
    Android Apk反编译得到Java源代码
    玩手游虽易保安全不易,打造手游App定制加密方案
    LR学习笔记2-LoadRunner目录分析
    LR学习笔记1-性能测试常见用语
    [MySql视图的使用]
    SQL实训
    Mysql_删除主键
    [SQL提数]函数的灵活使用
  • 原文地址:https://www.cnblogs.com/wooroc/p/15808363.html
Copyright © 2011-2022 走看看