问答详情
源自:2-4 应用揭秘

用互斥与同步知识写售票系统(最后一节视频有要求)

我在run()方法里运用了互斥与同步的知识,但无法实现三个线程售出五张票的功能,因为在售出一张票之后(完成操作后)做不到既能使线程不结束又能释放锁资源。

为了便于理解,我来解释一下:

要求(实现的功能)是这样的:三个窗口(线程)公平竞争五张票,哪些窗口可以售票,一个窗口可以售多少张票由系统决定,这意味着每次运行的结果都不一样。“希望线程不结束”是因为该线程售出一张票后仍然有机会售票,“又能释放锁资源”是因为其他线程也可以售票。

以下是我的代码,望大神赐教,不胜感激:

public class SoldTicketThread implements Runnable {

private int ticket=5;


Object lock=new Object();

public void run() {

synchronized(lock){

while(ticket<=0){

try {

lock.wait();

} catch (InterruptedException e) {

System.out.println("已售空,请等待");

}

}

/*while(ticket>0){

System.out.println(Thread.currentThread().getName()+

"卖出了一张票,剩余"+(--ticket)+"张票");

}*/

System.out.println(Thread.currentThread().getName()+

"卖出了一张票,剩余"+(--ticket)+"张票");

//Thread.yield();

lock.notifyAll();

}

}

}

在另一个文件(类)测试:

public class MainMenu {

public static void main(String[] args) {

SoldTicketThread window=new SoldTicketThread();


Thread wd1=new Thread(window,"窗口二");


Thread wd2=new Thread(window,"窗口一");


Thread wd3=new Thread(window,"窗口三");


wd1.start();

wd2.start();

wd3.start();


try {

wd1.join();

wd2.join();

wd3.join();

} catch (InterruptedException e) {

e.printStackTrace();

}


}

}


提问者:慕粉3687206 2016-07-28 22:31

个回答

  • 地铁时间ee
    2016-07-31 15:25:16
    已采纳

    public class SoldTicketThread implements Runnable {

    private int ticket = 5;


    private synchronized void sale() {

    if (ticket > 0) {

    System.out.println(Thread.currentThread().getName() + "卖出了一张票,剩余"

    + (--ticket) + "张票");

    try {

    Thread.sleep(100);

    } catch (InterruptedException e) {

    e.printStackTrace();

    }

    }

    }


    public void run() {

    while (ticket > 0) {

    sale();

    // 这里要确保进入卖票环节前就把资源锁住

    }

    }


    public static void main(String[] args) {

    SoldTicketThread window = new SoldTicketThread();

    Thread wd1 = new Thread(window, "窗口二");

    Thread wd2 = new Thread(window, "窗口一");

    Thread wd3 = new Thread(window, "窗口三");

    wd1.start();

    wd2.start();

    wd3.start();

    }

    }

    你本身的逻辑就出错了,卖票的操作肯定要在循环体里面,而且要锁定的内容是整个卖票过程的操作。