美文网首页
线程的同步和死锁1

线程的同步和死锁1

作者: 秋笙fine | 来源:发表于2019-01-24 21:14 被阅读0次

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

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

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

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抢票的时候,高并发情况下,票数需要加锁,否则就会出现票数为负的情况,或者同一张票卖给了两人,是灾难性的。因而线程安全的核心思想:"要么只读,要么加锁。"

相关文章

  • 线程的同步和死锁1

    本篇是为了同步问题的引出。 实际上所谓的同步指的就是多个线程访问同一资源所引出的问题。 范例:观察非同步情况下的操...

  • 并发 :线程间同步、锁、可重入锁及互斥锁

    线程间同步 线程间同步涉及线程互斥锁; 锁(Lock)容易导致死锁,可重入锁(RLock)则不会导致死锁,但每次 ...

  • 线程同步和线程死锁

    1.线程同步,一个关键字:synchronized 为什么有这个东西呢,假如有一个对象,里面有成员变量和方法,如果...

  • iOS 多线程面试题(死锁)

    死锁 死锁就是队列引起的循环等待 1、一个比较常见的死锁例子:主队列同步 在主线程中运用主队列同步,也就是把任务放...

  • GCD

    1、同步串行队列 2、同步并行队列 3、异步串行队列 4、异步并行队列 5、死锁 主线程中创建同步串行队列 主线程...

  • GCD 使用过程中的出现的死锁问题

    死锁 1、 主队列在主线程同步执行 下列代码写在 viewDidLoad 中: 上面死锁的写法是: ** 主队列...

  • 死锁现象及分析方法 之二 Window Java

    1 死锁 当多条线程以不同的顺序抢占同步资源的时候,就有可能发生死锁。 2 示例 如下图所示,线程1持有锁对象A而...

  • GCD分析(中)

    同步函数死锁 死锁现象 主线程因为同步函数的原因等着先执⾏任务 主队列等着主线程的任务执⾏完毕再执⾏⾃⼰的任务 主...

  • Synchronized关键字详解2(对非object持锁)

    4.死锁:同步方法容易造成死锁。Java线程死锁是一个经典的多线程问题,因为不同的线程都在等待根本不可能被释放的锁...

  • Java 并发编程——同步与死锁

    1. 同步与死锁 1.1 同步 说到线程,同步是一个不得不说的话题,为什么呢?因为多个线程访问同一资源时,如果不进...

网友评论

      本文标题:线程的同步和死锁1

      本文链接:https://www.haomeiwen.com/subject/lalujqtx.html