线程的同步和死锁1

本篇是为了同步问题的引出。

实际上所谓的同步指的就是多个线程访问同一资源所引出的问题。

范例:观察非同步情况下的操作(多人卖票问题)

package TestDemo;



class MyThread implements Runnable{//Runnable接口子类,也是线程公有对象,其实例化对象在堆中

    private int ticket=5;

    @Override
    public void run() {
        for (int i = 0; i < 20; i++) {
            if(this.ticket>0)
            System.out.println(Thread.currentThread().getName()+",sell ticket="+this.ticket--);
        }
    }   
}

public class TestDemo{
    
    public static void main(String[] args)throws Exception{
        MyThread mt=new MyThread();
    
        new Thread(mt,"seller A").start();
        new Thread(mt,"seller B").start();
        new Thread(mt,"seller C").start();
        new Thread(mt,"seller D").start();


    }
    
}
image.png

此时没有问题出现是因为在一个JVM进程下运行,并且没有受到任何影响,如果要想观察到问题,可以加入一个延迟。

package TestDemo;



class MyThread implements Runnable{//Runnable接口子类,也是线程公有对象,其实例化对象在堆中

    private int ticket=5;

    @Override
    public void run() {
        for (int i = 0; i < 20; i++) {
            if(this.ticket>0){
                try {
                    Thread.sleep(100);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            
            System.out.println(Thread.currentThread().getName()+",sell ticket="+this.ticket--);
            
            }
        }
    }   
}

public class TestDemo{
    
    public static void main(String[] args)throws Exception{
        MyThread mt=new MyThread();
    
        new Thread(mt,"seller A").start();
        new Thread(mt,"seller B").start();
        new Thread(mt,"seller C").start();
        new Thread(mt,"seller D").start();


    }
    
}

发现出现了脏数据。


image.png

不仅出现了重复数据,还出现了负数,这就是不同步的状况,整个卖票的步骤分为两步:
第一步:判断是否还有剩余的票数
第二步:减少剩余票数


image.png

我们可以将中间的休眠想象成高并发下的程序运行,压力增大情况下,如果不对票数进行同步加锁,就会出现脏数据,设想一下,12306抢票的时候,高并发情况下,票数需要加锁,否则就会出现票数为负的情况,或者同一张票卖给了两人,是灾难性的。因而线程安全的核心思想:"要么只读,要么加锁。"

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 一、进程和线程 进程 进程就是一个执行中的程序实例,每个进程都有自己独立的一块内存空间,一个进程中可以有多个线程。...
    阿敏其人阅读 7,400评论 0 13
  • 本文用来介绍 iOS 多线程中 GCD 的相关知识以及使用方法。这大概是史上最详细、清晰的关于 GCD 的详细讲...
    花花世界的孤独行者阅读 3,480评论 0 1
  • 文用来介绍 iOS 多线程中 GCD 的相关知识以及使用方法。通过本文,您将了解到: 1. GCD 简介 2. G...
    晓_我想去环游世界阅读 4,829评论 2 8
  • 长假前最后一个工作日,忙得飞起来,就为了给祖国母亲好好庆生,不被连环夺命call追杀。 一早到了就开始帮病人联系检...
    诸慧的身心园地阅读 1,254评论 0 0
  • 人生如旅,是不断的出发,也是随时的止步。从湖南农村的老家到国际金融都市上海,一切都跟随心的声音。 一如村上春树所说...
    一粒简单阅读 1,020评论 0 0