Java的线程上锁造成的问题

public class Piao implements Runnable{

Integer p=5;
@Override
public synchronized void run() {

    synchronized(p) {
    if(p>0) {

        System.out.println("卖出了第"+p+"张票");
        p--;

    }
    else {
        System.out.println("没了");
    }
    }
}

public static void main(String[] args) {
Piao c=new Piao ();

    new Thread(c).start();
    new Thread(c).start();
    new Thread(c).start();
    new Thread(c).start();
    new Thread(c).start();

}
}
就是这种卖票的问题,如果锁方法;就会让一个线程卖完全部票,如果锁票数,就会出现两个线程卖同一张票的问题,请问怎么处理?

4个回答

【1】如果锁方法,就会让一个线程卖完全部票,,,,

你写的这个,,没有循环,只有一个if,,,一个线程只能买一张票。买完就,,执行完了。

【2】如果锁票数,就会出现两个线程卖同一张票的问题,
不会出现两个线程卖同一张票的问题,,

synchronized(p),,所有线程都会卡到这里,,等待运行线程释放 p ,
释放之后才会有下一个线程执行,进行 if 判断,,不会出现买同一张票的情况。

我之前写了一个多线程买票的demo,,,你可以参考参考。:

 package xatu.zsl.main;

/**
 * Created by zsl on 2017/8/9.
 */
public class Demo {
    public static void main(String[] args) {
        //使用同一个runnable保证 tickateNum只初始化一次
        MyThread myThread = new MyThread();
        Thread thread1 = new Thread(myThread, "窗口1");
        Thread thread2 = new Thread(myThread, "窗口2");
        Thread thread3 = new Thread(myThread, "窗口3");
        Thread thread4 = new Thread(myThread, "窗口4");
        System.out.println("开始买票!!");
        thread1.start();
        thread2.start();
        thread3.start();
        thread4.start();
        System.out.println("买票结束!!");
    }
}

class MyThread implements Runnable {

    //初始化有十张票,,设置为可见的整形,防止并发操作出错
    volatile int ticketNum = 100;
    Object object = new Object();

    public void run() {
        while (this.ticketNum > 0) {
            synchronized (object) {//保证扣票和输出是一个整体
                if (this.ticketNum > 0) {   //防止卖出负票
                    //售出一张
                    this.ticketNum = this.ticketNum - 1;
                    System.out.println(Thread.currentThread().getName() + "售出一张火车票,还剩" + this.ticketNum + "张");
                } else {
                    return;
                }
            }
        }
    }
}
Small_Mouse0
小鼠标丶 回复xhjwyy: 嗯,你说的对,,,volatile确实是无用的,,,我一开始只使用volatile,发现输出的剩余张数顺序不对,后来加了同步锁,保证了输出和扣票成一个整体,,然后就没删这个volatile,,又更新了一个错误,谢谢哈
2 年多之前 回复
u010515202
xhjwyy 回复小鼠标丶: 你都已经把买票方法加锁了,又何必多此一举给票数加volatile呢
2 年多之前 回复
u010515202
xhjwyy 你都已经把买票方法加锁了,又何必多此一举给票数加volatile呢
2 年多之前 回复
Small_Mouse0
小鼠标丶 更正一个错误:主线程这个输出不对, System.out.println("买票结束!!");去掉即可,,知识为了说明问题,,买票结束可在MyThread类的run()方法中加入对票数判断的代码。
2 年多之前 回复

volatile锁票数

事实上目前关于买票基本上都是采用分布式策略 这种悲观锁很容易导致死锁

很遗憾,单纯就代码看,楼主的两个问题都不会出现。完测试这两个问题,楼上代码可以参考!!

Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问