线程数据安全02-----(同步代码块)解决对个窗口卖出同一张票的

问题分析:出现了数据安全问题 , 主要原因就是同一时间有多个线程操作了共享的数据

我们这个程序一开始会出现多个窗口卖出了同一张票
这种情况就是出现了数据安全的问题

出现数据安全的问题的原因
1.是否有多线程环境
2.是否有共享数据 这里的共享数据就是 tickets
3.是否有多条语句操作共享数据 这里就是对数据的输出 和++ 操作
解方法就是给程序加锁,在某一段时间只能有一个程序操作共享数据破坏第三个条件

具体代码的分析:

private int tickets = 1;
public void run() {

//现在窗口一 窗口二 窗口三 都跑到这里了
//现在tickets = 1
//假设窗口一抢占到了资源
while (true){

if(tickets <= 200){ //100z张票
System.out.println(Thread.currentThread().getName()+"正在出售第"+tickets+"张票");

//窗口一 线程到这里了 已经卖出了第一章票 但是现在tickets = 1
突然cpu资源被线程二抢走了 此时 tickets = 1 还没进行 ++
所以线程二就又卖出了第二张票


//但是我不明白为什么有时候已经卖出了第58还是会出现
又卖出了 第一张票这么神奇的事情 ticket都已经变为58 怎么又会变为一
难道是因为我的电脑太垃圾了线程卡了??

tickets++;
}
}
}

*/

使用同步代码块解决数据安全问题
解决多个窗口同时卖出同一张票
卖票的类


public class SaleTickets implements Runnable {

private int tickets = 1;

private Object obj =new Object() ;

@Override
public void run() {


//窗口一直等着别人来买票
while (true){

//synchronized (new Object()){
//这样写是错误的 ,因为每一个线程走到这里都会new 一个object对象 就是new出来三把锁
//这样是不行的 要使用一个线程来锁住按个线程 所以要把 new Object 放在外面

synchronized (obj){
if (tickets <= 100){

System.out.println(Thread.currentThread().getName()+"卖出了第:"+tickets+"张票");
//票数加一
tickets++;

//卖票员休息一下
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}

}

}

}

}
}

测试类


public class Test {


/*
我们这个程序一开始会出现多个窗口卖出了同一张票
这种情况就是出现了数据安全的问题

出现数据安全的问题的原因
1.是否有多线程环境
2.是否有共享数据 这里的共享数据就是 tickets
3.是否有多条语句操作共享数据 这里就是对数据的输出 和++ 操作

if (tickets <= 100){

System.out.println(Thread.currentThread().getName()+"卖出了第:"+tickets+"张票");
//票数加一
tickets++;
}



//怎么解决这种情况
吧多条语句操作共享数据的代码用一把锁给锁起来 让任意时刻只有一个线程执行即可

可以使用同步代码块实现 格式:
synchronized(任意对象){

多条语句操作共享数据的代码

}




//我们分析一下同步代码快的运行 流程
while (true){

//tickets = 100 ;
//t1,t2,t3 都进来了
//假设t1抢占到了资源

synchronized (obj){
if (tickets <= 100){

System.out.println(Thread.currentThread().getName()+"卖出了第:"+tickets+"张票");
//票数加一
tickets++;

//卖票员休息一下
try {
Thread.sleep(100);
//t1到这里休息了 假如此时t2抢占到了资源 但是此时锁还在锁着 t2进不来的
} catch (InterruptedException e) {
e.printStackTrace();
}

}

}

//到这里t1出来了 锁就解开了 t2就可以进去了



*/


public static void main(String[] args) {

//创建线程资源对象
SaleTickets saleTickets = new SaleTickets();

//创建线程对象
Thread thread1= new Thread(saleTickets,"窗口一");
Thread thread2= new Thread(saleTickets,"窗口二");
Thread thread3= new Thread(saleTickets,"窗口三");


//开始线程
thread1.start();
thread2.start();
thread3.start();

//输出之后确实发现了有几个线程输出了同一个对象
// 怎么解决这这问题??? 使用锁那


}




}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值