第一の溶液の同期ブロックjavaSE--スレッドの安全性の問題(アナログチケット)

1.ケースのチケットシミュレーションスレッド安全性の問題

public class TicketImpl implements Runnable {
    private int ticket = 100;
    @Override
    public void run() {
        /**
         * 在这里模拟卖票
         *      为了增加线程安全问题出现的概率使用sleep适当延时增加其他线程访问到ticket概率
         * */
        while(ticket>0){
            try {
                Thread.sleep(20);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()+"卖出第-->"+ticket+"");
            ticket--;
        }
    }
}

テストケース

public class DemoThreadSafe {
    public static void main(String[] args) {
        //模拟线程安全问题
        TicketImpl ticket = new TicketImpl();
        Thread t1 = new Thread(ticket);
        Thread t2 = new Thread(ticket);
        Thread t3 = new Thread(ticket);
        t1.start();
        t2.start();
        t3.start();
       
        System.out.println("=============================");

    }
}

結果

Thread-2卖出第-->100
Thread-0卖出第-->100
Thread-1卖出第-->100

Thread-0卖出第-->3
Thread-2卖出第-->1

Thread-0卖出第-->1
Thread-2卖出第-->0
Thread-1卖出第-->-1

そのようなAスレッド安全性の問題の結果から分かるように:

        1. 3个线程出现多次卖票 --->第100张票卖出多次
        2. 出现漏卖票的情况 --->第三张票没有卖出
        3. 出现卖出第0张和第-1张这种非法的票

2.synchronized同期ブロックアドレスセキュリティスレッド

同步代码块的原理: 使用了一个对象锁/线程锁/对象监视器--->这个对象锁可以是任意的
        1.当多个线程一起争夺cpu的执行权的时候
        2.第一个执行的线程当运行的同步代码块的时候首先判断有没有对象锁,如果有取走对象锁,
             并执行同步代码块的内容,当前线程执行完毕后归还对象锁
        3.当第二个线程运行到同步代码块的时候,同样判断有没有对象锁,如果没有则进入阻塞等待状态,直到对象锁被归还后
    		  再次与其他线程争夺cpu执行权,取对象.

コードの実装:

public class SaveTicketImpl implements Runnable {
    private int ticket = 100;
    //在这里使用同步代码块解决线程安全问题-->对象锁必须在run方法外边定义,以保证对象锁唯一
    Object o = new Object();
    @Override
    /**
        * 在这里模拟卖票
        *      为了增加线程安全问题出现的概率使用sleep适当延时增加其他线程访问到ticket概率
        * */
    public void run() {
        synchronized (o){
            while(ticket>0){
                try {
                    Thread.sleep(20);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName()+"卖出第-->"+ticket+"张票");
                ticket--;
            }
        }

    }
}


public class DemoThreadSafe {
    public static void main(String[] args) {
        //模拟线程安全问题
        TicketImpl ticket = new TicketImpl();
        Thread t1 = new Thread(ticket);
        Thread t2 = new Thread(ticket);
        Thread t3 = new Thread(ticket);
        t1.start();
        t2.start();
        t3.start();
        System.out.println("=============================");

    }
}

結果:


Thread-0卖出第-->100张票
Thread-0卖出第-->99张票
Thread-0卖出第-->98张票
Thread-0卖出第-->97张票
.
.
.
Thread-0卖出第-->3张票
Thread-0卖出第-->2张票
Thread-0卖出第-->1张票

スレッドの安全性の問題の結果から分かるように解決されました!

リリース元の4件の記事 ウォンの賞賛4 ビュー201

おすすめ

転載: blog.csdn.net/weixin_42183953/article/details/104629979