码迷,mamicode.com
首页 > 编程语言 > 详细

线程不安全三大问题_解决 同步方法及同步块

时间:2020-04-30 13:44:33      阅读:71      评论:0      收藏:0      [点我收藏+]

标签:new   trace   owa   cat   inter   one   nts   while   extends   

package com.qiliang.demo13_线程同步安全;
// 线程同步安全问题 , 卖票案例演示
public class UnSafeBuyTicket {
    public static void main(String[] args) {
        BuyTicket station = new BuyTicket();

        new Thread(station,"小A").start();
        new Thread(station,"小B").start();
        new Thread(station,"黄牛党").start();
    }
}


class BuyTicket implements Runnable{
    // 定义票数
    private int ticketNums = 10;
    // 线程停止的标志位
    boolean flag = true;
    @Override
    public void run() {
        // 买票
        while (flag){
            buy();
        }
    }

    // synchronized 同步方法
    private synchronized void buy() {
        // 判断是否有票
        if(ticketNums<=0){
            flag = false;
            return;
        }

        // 模拟延时,放大问题的发生性
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        // 买票
        System.out.println(Thread.currentThread().getName()+"拿到"+ticketNums--);
    }
}
// 线程不安全, 有负数
/*
黄牛党拿到10
小B拿到9
小A拿到8
黄牛党拿到7
小B拿到6
小A拿到5
黄牛党拿到4
小B拿到3
小A拿到2
黄牛党拿到1
小B拿到0
小A拿到-1
 */

``` java
package com.qiliang.demo13_线程同步安全;

// 线程同步安全问题,不安全的取钱案例
public class UnSafeBank {
    public static void main(String[] args) {
        Account account = new Account(1000, "结婚基金");

        Drawing xiaoli = new Drawing("小李", account, 50);
        Drawing xiaowang = new Drawing("小王", account, 100);

        xiaoli.start();
        xiaowang.start();

    }

}

// 账户
class Account{
    int money;  // 余额
    String name; // 卡名

    public Account(int money, String name) {
        this.money = money;
        this.name = name;
    }
}

// 银行 : 模拟取款
class Drawing extends Thread{
    Account account; // 账户
    // 取了多少钱
    int drawingMoney;
    // 现在手里有多少钱
    int nowMoney;

    public Drawing(String name, Account account, int drawingMoney) {
        super(name);
        this.account = account;
        this.drawingMoney = drawingMoney;

    }

    // 取钱

    @Override
    public void run() {
       synchronized (account){
           // 判断有没有钱
           if (account.money-drawingMoney<0) {
               System.out.println(Thread.currentThread().getName()
                       +"钱不够,取不了!");
               return;
           }

           // 模拟延时
           try {
               Thread.sleep(1000);
           } catch (InterruptedException e) {
               e.printStackTrace();
           }
           // 卡内余额 = 余额 - 你取的钱
           account.money = account.money - drawingMoney;
           // 你手里的钱
           nowMoney = nowMoney + drawingMoney;

           System.out.println(account.name+"余额为"+account.money);
           // Thread.currentThread().getName() = this.getName()
           System.out.println(this.getName()+"手里的钱:"+nowMoney);
       }

    }
}

``` java
package com.qiliang.demo13_线程同步安全;

import java.util.ArrayList;

// 线程不安全的集合
public class UnSafeList {
    public static void main(String[] args) throws InterruptedException {
        ArrayList<String> list = new ArrayList<>();
        for (int i = 0; i < 10000; i++) {
            new Thread(()->{
                synchronized (list){
                list.add(Thread.currentThread().getName());
                }

            }).start();
        }
        Thread.sleep(3000);   // 9997  i=10000
        System.out.println(list.size()); // 918  i=1000
    }
}

线程不安全三大问题_解决 同步方法及同步块

标签:new   trace   owa   cat   inter   one   nts   while   extends   

原文地址:https://www.cnblogs.com/liqiliang1437/p/12807981.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!