SE-8-同步代码块-注意事项

该文章通过一个Java示例展示了多线程环境下卖票程序可能出现的超卖和重复票问题,原因是多个线程并发访问共享资源时破坏了原子性。解决方案是使用同步代码块确保对票数的操作成为原子操作,从而避免线程安全问题,但同步可能会降低效率。
摘要由CSDN通过智能技术生成
package com.itheima._6卖票;

public class Test {
    public static void main(String[] args) {
        MyTicket my = new MyTicket();//三个线程操作同一个ticket
        Thread t1 = new Thread(my);
        Thread t2 = new Thread(my);
        Thread t3 = new Thread(my);

        t1.setName("窗口1 ");
        t2.setName("窗口2 ");
        t3.setName("窗口3 ");

        t1.start();
        t2.start();
        t3.start();
    }
}

package com.itheima._6卖票;

public class MyTicket implements Runnable{//这里实现implements 或者继承extends 都可以
    private int ticket = 100;//100张票 //ticket 被3个线程所共享
    /*private Object obj = new Object();//这个成员变量obj被3个线程所共享 //也可以synchronized (obj)
    private Student stu = new Student();//也可以synchronized (stu)*/

    //三个线程共同操作以下代码
    @Override
    public void run() {
        //如果从这里开始用 synchronized (this){ }括起来,会一直到ticket <= 0,第2个线程进来,票已经卖完了
        while(true){
            //_1同步代码块 ,要求锁对象唯一即可(唯一就是 对多个线程共同拥有的),区别于( new Object() )
            synchronized (this) {//this是当前对象MyTicket,MyTicket只创建1次 //this和my的地址值是一样的
                if(ticket <= 0){
                    break;
                }else{
                    //休眠10毫秒
                    try {
                        Thread.sleep(10);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                    ticket--;//每卖出去 减一张
                    // 3个重复票:3个线程操作同1个ticket,所以一开始是99 98 97,在值输出之前会被覆盖,所以都是97重复票
                    //2个超卖票:-1和-2。3个线程到了休眠处,第1个线程苏醒后,i--是0,第2和第3线程是在前面线程基础上i--.
                    System.out.println(Thread.currentThread().getName()+"在卖票,还剩下"+ticket+"张");
                }
            }

        }
    }
}

package com.itheima._6卖票;

public class Student {
}

窗口2 在卖票,还剩下99张
窗口2 在卖票,还剩下98张
窗口2 在卖票,还剩下97张
窗口2 在卖票,还剩下96张
窗口2 在卖票,还剩下95张
窗口2 在卖票,还剩下94张
窗口2 在卖票,还剩下93张
窗口2 在卖票,还剩下92张
窗口2 在卖票,还剩下91张
窗口2 在卖票,还剩下90张
窗口2 在卖票,还剩下89张
窗口2 在卖票,还剩下88张
窗口2 在卖票,还剩下87张
窗口2 在卖票,还剩下86张
窗口2 在卖票,还剩下85张
窗口2 在卖票,还剩下84张
窗口2 在卖票,还剩下83张
窗口2 在卖票,还剩下82张
窗口2 在卖票,还剩下81张
窗口2 在卖票,还剩下80张
窗口2 在卖票,还剩下79张
窗口2 在卖票,还剩下78张
窗口2 在卖票,还剩下77张
窗口2 在卖票,还剩下76张
窗口2 在卖票,还剩下75张
窗口2 在卖票,还剩下74张
窗口2 在卖票,还剩下73张
窗口2 在卖票,还剩下72张
窗口2 在卖票,还剩下71张
窗口2 在卖票,还剩下70张
窗口2 在卖票,还剩下69张
窗口2 在卖票,还剩下68张
窗口2 在卖票,还剩下67张
窗口2 在卖票,还剩下66张
窗口2 在卖票,还剩下65张
窗口2 在卖票,还剩下64张
窗口2 在卖票,还剩下63张
窗口2 在卖票,还剩下62张
窗口2 在卖票,还剩下61张
窗口2 在卖票,还剩下60张
窗口2 在卖票,还剩下59张
窗口2 在卖票,还剩下58张
窗口2 在卖票,还剩下57张
窗口2 在卖票,还剩下56张
窗口2 在卖票,还剩下55张
窗口2 在卖票,还剩下54张
窗口2 在卖票,还剩下53张
窗口2 在卖票,还剩下52张
窗口2 在卖票,还剩下51张
窗口2 在卖票,还剩下50张
窗口2 在卖票,还剩下49张
窗口2 在卖票,还剩下48张
窗口2 在卖票,还剩下47张
窗口2 在卖票,还剩下46张
窗口2 在卖票,还剩下45张
窗口2 在卖票,还剩下44张
窗口2 在卖票,还剩下43张
窗口2 在卖票,还剩下42张
窗口2 在卖票,还剩下41张
窗口2 在卖票,还剩下40张
窗口2 在卖票,还剩下39张
窗口2 在卖票,还剩下38张
窗口2 在卖票,还剩下37张
窗口2 在卖票,还剩下36张
窗口2 在卖票,还剩下35张
窗口2 在卖票,还剩下34张
窗口2 在卖票,还剩下33张
窗口2 在卖票,还剩下32张
窗口2 在卖票,还剩下31张
窗口2 在卖票,还剩下30张
窗口2 在卖票,还剩下29张
窗口2 在卖票,还剩下28张
窗口2 在卖票,还剩下27张
窗口2 在卖票,还剩下26张
窗口2 在卖票,还剩下25张
窗口2 在卖票,还剩下24张
窗口2 在卖票,还剩下23张
窗口2 在卖票,还剩下22张
窗口2 在卖票,还剩下21张
窗口2 在卖票,还剩下20张
窗口2 在卖票,还剩下19张
窗口2 在卖票,还剩下18张
窗口2 在卖票,还剩下17张
窗口2 在卖票,还剩下16张
窗口2 在卖票,还剩下15张
窗口2 在卖票,还剩下14张
窗口2 在卖票,还剩下13张
窗口2 在卖票,还剩下12张
窗口2 在卖票,还剩下11张
窗口2 在卖票,还剩下10张
窗口2 在卖票,还剩下9张
窗口2 在卖票,还剩下8张
窗口2 在卖票,还剩下7张
窗口2 在卖票,还剩下6张
窗口2 在卖票,还剩下5张
窗口2 在卖票,还剩下4张
窗口2 在卖票,还剩下3张
窗口2 在卖票,还剩下2张
窗口2 在卖票,还剩下1张
窗口2 在卖票,还剩下0张

一.

1. 超卖

2. 重复票

原因:
   在多线程情况下,在操作同一资源(变量,数据,代码块)破坏了原子操作!

二.解决方案:

将一系列操作,视为原子操作,应该给予保证!
将视为原子操作的代码片段 上锁!

1.同步代码块

同步代码块 sychronized

//格式 sychronzied(锁对象){

//要求锁对象 对于 所有的线程是 唯一的    

}

注意事项

1. 目的保证同步代码块的原子操作

   

 弊端:效率较低

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值