okyesok1515 2019-01-12 14:40 采纳率: 100%
浏览 661
已采纳

Java中关于原子变量和多线程安全问题

自学java碰到些问题,向各位大佬们请教下
多线程安全问题产生的前提 是不是 多线程对共享数据进行了非原子操作
既然是共享数据进行非原子性操作的化,那用AtomicXxx类应该能解决吧
但是....

package Thread_01;

import java.util.concurrent.atomic.AtomicInteger;

class TicketSale2 implements Runnable{
    //private int tickets=100;
    AtomicInteger tickets=new AtomicInteger(10);
    Object object=new Object();
    //线程任务为售票,所以将该任务在run方法中执行
    public void run(){
        while(true) {
        //synchronized (object) {

            if(tickets.get()>0) {
                try {
                    Thread.sleep(20);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName()+"您好,您的票号为"+tickets.getAndDecrement());
            }
            else{break;}
        //}
        }
    }
}
public class TicketDemo3 {
    public static void main(String[] args) {
        //线程任务对象
        TicketSale2 ticketSale=new TicketSale2();
        //线程对象
        Thread t1=new Thread(ticketSale);
        Thread t2=new Thread(ticketSale);
        Thread t3=new Thread(ticketSale);
        Thread t4=new Thread(ticketSale);
        t1.start();
        t2.start();
        t3.start();
        t4.start();

    }
}

还是会产生线程安全问题...这是为什么呢 还望大佬们抽空解答下
图片说明

  • 写回答

1条回答 默认 最新

  • 舍文 2019-01-12 16:11
    关注

    tickets.get() 是原子操作,tickets.getAndDecrement()是原子操作。但是两个操作合起来就不具备原子性了。判断和操作分离了。
    Thread-2 , Thread-3, Thread-1 执行tickets.get() 都是1 ,但是sleep20毫秒以后,Thread-2先执行tickets.getAndDecrement()于是打印0,
    Thread-3接着执行tickets.getAndDecrement(),但是tickets当前值为0,于是打印-1 ,Thread-1最后执行tickets.getAndDecrement(),但是tickets
    的当前值为-1,于是打印-2

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 如何对参数分析结构进行绘图
  • ¥15 做一个满足376和698规约的集中器程序
  • ¥50 python如何用抖音这个接口输入抖音ID查询用户信息
  • ¥30 关于移动Web网页使用TinyMCE富文本编辑器上传图片后的光标定位、压缩等几个问题如何解决:
  • ¥40 activeMq在同服务器centos8下消费很慢
  • ¥20 为什么zynq CAN IP 无法进入config配置模式,XCan_SelfTest函数失效?
  • ¥15 Pycharm中程序直接运行可以但进入调试报错
  • ¥15 MATLAB动图问题
  • ¥15 有段代码不知道怎么理解,const isToken = (config.headers || {}).isToken === false
  • ¥15 我的显卡支持CUDA最高版本是12.3,这个版本也支持VS 2022 17.0这种情况下如果我想下载CUDA11.8,需要下载旧版本的VS2022吗