4.线程同步(重点)

1
摘要由CSDN通过智能技术生成

1、并发 :

同一个对象被多个线程同时操作,如十个人同时抢一张火车票

2、线程同步机制

-线程同步

现实生活中,我们会遇到 ” 同一个资源 , 多个人都想使用 ” 的问题 , 比如,食堂排队打饭 , 每个人都想吃饭 , 最天然的解决办法就是 , 排队 ,一个个来。
处理多线程问题时 , 多个线程访问同一个对象 , 并且某些线程还想修改这个对象(如银行取钱),这时候我们就需要线程同步 , 线程同步其实就是一种等待机制 , 多个需要同时访问此对象的线程进入这个对象的等待池形成队列, 等待前面线程使用完毕 , 下一个线程再使用

- 队列 和 锁
为了保证线程同步 的安全性需要:队列+锁
在这里插入图片描述
由于同一进程的多个线程共享同一块存储空间 , 在带来方便的同时,也带来了访问冲突问题 , 为了保证数据在方法中被访问时的正确性 , 在访问时加入锁机制 synchronized , 当一个线程获得对象的排它锁 , 独占资源 , 其他线程必须等待 , 使用后释放锁即可。同时使用锁存在以下问题 :

一个线程持有锁会导致其他所有需要此锁的线程挂起 ;
在多线程竞争下 , 加锁 , 释放锁会导致比较多的上下文切换和调度延时,引起性能问题 ;
如果一个优先级高的线程等待一个优先级低的线程释放锁会导致优先级倒置 , 引起性能问题

3、三大不安全案例

  1. 不安全的买票
//不安全的买票
//线程不安全,有零和负数
public class unsafeBuyTickets {
   
    public static void main(String[] args) {
   
        BuyTickets buyTickets = new BuyTickets();
        new Thread(buyTickets,"凸凸").start();
        new Thread(buyTickets,"凹凹").start();
        new Thread(buyTickets,"黄牛党").start();
    }

}

class BuyTickets implements Runnable{
   
    //票
    private int ticketsNums = 10;
    private Boolean flag = true;//外部停止方式
    @Override
    public void run() {
   
       buy();
    }

    public void buy(){
   
        while(flag){
   
            if(ticketsNums <= 0){
   
                flag = false;
                return;
            }
            //模拟时延
            try {
   
                Thread.sleep(100);
            } catch (InterruptedException e) {
   
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + "拿到了第" + ticketsNums-- + "张票");

        }

    }
}

运行截图:
在这里插入图片描述

  1. 不安全的取钱
//两个人去银行取钱,账户
public class unsafeBank {
   

    public static void main(String[] args) {
   
        Account account = new Account(10000,"恋爱基金");
        Drawing me = new Drawing(account,9000,2000);
        Drawing boyFriend = new Drawing(account,2000,8000);
        new Thread(me,"我").start();
        new Thread(boyFriend,"男朋友").start();
    }
}
//账户
class Account{
   
    int money;//余额
    String name;//卡名

    public Account(int money, String name) {
   
        this.money = money;
        this.name = name;
    }
}
//模拟银行取钱
class Drawing implements Runnable{
   
    //账户
    Account account;
    //取多少钱
    int drawingMoney;
    //手里有多少钱
    int nowMoney;

    public Drawing(Account account, int drawingMoney, int nowMoney) {
   
        this.account = account;
        this.drawingMoney = drawingMoney;
        this.nowMoney 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值