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();

}
}
就是这种卖票的问题,如果锁方法;就会让一个线程卖完全部票,如果锁票数,就会出现两个线程卖同一张票的问题,等待和睡眠都不好使的。请问怎么处理,谢谢解答

3个回答

【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();
    }
}

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;
                }
            }
        }
    }
}

volatile锁票数

一天了,楼主还没解决?

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