同步问题,卖票的一段代码
这是一个多线程的问题,是同时三个线程运行,进行卖票,但是到最后有可能出现同时两个或者三个线程进入到程序导致多卖票,就使用了synchronized 同步,但是还是会出现多卖票问题,请大佬给看看哪里出现了问题
package com.dy.sym.Ticket;
/**
* @ClassName SellTicket03
* @AuThor 微笑
* @date 2022/9/5 11:03
* @Param
* @version 1.0
*/
public class SellTicket03 {
public static void main(String[] args) {
SellTicket04 sellTicket04 = new SellTicket04();
new Thread(new SellTicket04()).start();
new Thread(new SellTicket04()).start();
new Thread(new SellTicket04()).start();
}
}
class SellTicket04 implements Runnable{
private static int sellTicket = 100;
public boolean loop = true;
public synchronized void sell(){//同步方法
if (sellTicket <= 0){
System.out.println("售票结束");
loop = false;
return;
}
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("窗口" + Thread.currentThread().getName() + "售出一张票" +
"剩余票数" + (--sellTicket));
}
@Override
public void run() {
while (loop){
sell();
}
}
}
需要用到锁~网上有C#的这个例子 把sell方法放到runnable外面 本帖最后由 jockiller 于 2022-9-5 13:19 编辑
你的写法,同步加在了实例方法上。三个线程就是三个实例。。写到方法里面,然后把同步作用在类上就行了
synchronized (SellTicket04.class) {
}
不过即使这样,也仅仅能保证单机同步,建议直接用锁,将来升级分布式也方便。
你那个写法,通常用在静态方法,spring托管的单例对象上 synchronized写在非静态方法上,锁对象是this,也就是当前对象,你每次都new了一个SellTicket4实例,导致不是一个锁对象,而且loop也不是静态属性,每个实例中的loop完全不相关,想实现线程安全,就用同一个SellTicket4实例 大佬!学习了! 可以使用redis和MQ等中间件 可以看看最近尚硅谷发布的分布式视频,很不错 这里synchronized锁的不是同一个对象,所以没有意义。。。 SellTicket04 sellTicket04 = new SellTicket04();
new Thread(new SellTicket04()).start();
new Thread(new SellTicket04()).start();
new Thread(new SellTicket04()).start();
// 改为
SellTicket04 sellTicket04 = new SellTicket04();
new Thread(sellTicket04).start();
new Thread(sellTicket04).start();
new Thread(sellTicket04).start();
页:
[1]