CY_99 2022-03-09 14:48 采纳率: 0%
浏览 163

java多线程加synchronized锁后变为单线程

问题遇到的现象和发生背景

复习多线程的时,在模拟窗口卖票场景发现加上线程锁之后只有一个窗口在出售票。不加线程锁时三个窗口都可以买票但是卖出的票可能重复或有票没有售出。

问题相关代码
public class runableImpl implements Runnable {

    private Object object = new Object();
    private int ticket = 0;

    @Override
    public void run() {
        synchronized (object) {
            try {
                Thread.sleep(100);
                while (true) {
                    if (ticket >= 100) {
                        return;
                    }
                    ticket++;
                    System.out.println(Thread.currentThread().getName() + ":抢到第" + ticket + "张票");
                }

            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

//测试
class TestRunable {
    public static void main(String[] args) {
        runableImpl runable = new runableImpl();
        Thread thread = new Thread(runable, "窗口001");
        Thread thread2 = new Thread(runable, "窗口002");
        Thread thread3 = new Thread(runable, "窗口003");
        thread.start();
        thread2.start();
        thread3.start();
    }
}

运行结果及报错内容

上述代码结果为同一个窗口售出了所有票。第一张票是由谁卖出,就会由这个窗口把票卖完。

img

我的解答思路和尝试过的方法

我尝试增加票数和睡眠时间但是都是同一个窗口卖完的票。三个线程谁先进入方法就会由这个线程把票卖完。

我想要达到的结果

一百张票由多个线程一起售卖,并且没有重复票售出或漏出售票。

  • 写回答

2条回答 默认 最新

  • Tomshidi 2022-03-09 14:55
    关注

    改成这样

    public class RunnableImpl implements Runnable {
        private Object object = new Object();
        private int ticket = 0;
    
        @Override
        public void run() {
                try {
                    while (true) {
                        Thread.sleep(100);
                        synchronized (object) {
                            if (ticket >= 100) {
                                return;
                            }
                            ticket++;
                            System.out.println(Thread.currentThread().getName() + ":抢到第" + ticket + "张票");
                        }
                    }
    
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
        }
    }
    
    评论

报告相同问题?

问题事件

  • 创建了问题 3月9日

悬赏问题

  • ¥15 为什么eclipse不能再下载了?
  • ¥15 编辑cmake lists 明明写了project项目名,但是还是报错怎么回事
  • ¥15 关于#计算机视觉#的问题:求一份高质量桥梁多病害数据集
  • ¥15 特定网页无法访问,已排除网页问题
  • ¥50 如何将脑的图像投影到颅骨上
  • ¥15 提问一个关于vscode相关的环境配置问题,就是输入中文但是显示不出来,代码在idea可以显示中文,但在vscode不行,不知道怎么配置环境
  • ¥15 netcore使用PuppeteerSharp截图
  • ¥20 这张图页头,页脚具体代码该怎么写?
  • ¥20 WPF MVVM模式 handycontrol 框架, hc:SearchBar 控件 Text="{Binding NavMenusKeyWords}" 绑定取不到值
  • ¥15 需要手写数字信号处理Dsp三个简单题 不用太复杂