我在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();
}
}
}
16年的帖子 19年的回答。。。
class MyThread2 implements Runnable{ private int ticketsCont = 100;//一共5张火车票 private final Object lockObj = new Object(); @Override public void run() { while (true){ synchronized (lockObj){ while (ticketsCont<=0){ System.out.println(Thread.currentThread().getName()+"没票了"); try { lockObj.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } ticketsCont--; //如果还有票,就卖掉一张 System.out.println(Thread.currentThread().getName()+"卖了一张票,剩余票数为"+ticketsCont); try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } lockObj.notifyAll(); } } } } public class TicketsRunnable { public static void main(String[] args) { MyThread2 mt =new MyThread2(); //创建三个线程,模拟三个窗口卖票 Thread th1 = new Thread(mt,"窗口1"); Thread th2 = new Thread(mt,"窗口2"); Thread th3 = new Thread(mt,"窗口3"); //启动这三个线程 th1.start(); th2.start(); th3.start(); } }
运行结果 我的可以实现 你可以参考一下 有问题可以探讨哈
窗口1卖了一张票,剩余票数为99 窗口1卖了一张票,剩余票数为98 窗口1卖了一张票,剩余票数为97 窗口1卖了一张票,剩余票数为96 窗口1卖了一张票,剩余票数为95 窗口1卖了一张票,剩余票数为94 窗口1卖了一张票,剩余票数为93 窗口1卖了一张票,剩余票数为92 窗口1卖了一张票,剩余票数为91 窗口1卖了一张票,剩余票数为90 窗口1卖了一张票,剩余票数为89 窗口1卖了一张票,剩余票数为88 窗口1卖了一张票,剩余票数为87 窗口1卖了一张票,剩余票数为86 窗口1卖了一张票,剩余票数为85 窗口1卖了一张票,剩余票数为84 窗口3卖了一张票,剩余票数为83 窗口3卖了一张票,剩余票数为82 窗口3卖了一张票,剩余票数为81 窗口2卖了一张票,剩余票数为80 窗口2卖了一张票,剩余票数为79 窗口2卖了一张票,剩余票数为78 窗口2卖了一张票,剩余票数为77 窗口3卖了一张票,剩余票数为76 窗口3卖了一张票,剩余票数为75 窗口3卖了一张票,剩余票数为74 窗口3卖了一张票,剩余票数为73 窗口3卖了一张票,剩余票数为72 窗口3卖了一张票,剩余票数为71 窗口3卖了一张票,剩余票数为70 窗口3卖了一张票,剩余票数为69 窗口3卖了一张票,剩余票数为68 窗口3卖了一张票,剩余票数为67 窗口3卖了一张票,剩余票数为66 窗口3卖了一张票,剩余票数为65 窗口3卖了一张票,剩余票数为64 窗口3卖了一张票,剩余票数为63 窗口3卖了一张票,剩余票数为62 窗口3卖了一张票,剩余票数为61 窗口1卖了一张票,剩余票数为60 窗口1卖了一张票,剩余票数为59 窗口1卖了一张票,剩余票数为58 窗口1卖了一张票,剩余票数为57 窗口1卖了一张票,剩余票数为56 窗口1卖了一张票,剩余票数为55 窗口1卖了一张票,剩余票数为54 窗口1卖了一张票,剩余票数为53 窗口1卖了一张票,剩余票数为52 窗口1卖了一张票,剩余票数为51 窗口1卖了一张票,剩余票数为50 窗口1卖了一张票,剩余票数为49 窗口1卖了一张票,剩余票数为48 窗口1卖了一张票,剩余票数为47 窗口1卖了一张票,剩余票数为46 窗口1卖了一张票,剩余票数为45 窗口1卖了一张票,剩余票数为44 窗口1卖了一张票,剩余票数为43 窗口1卖了一张票,剩余票数为42 窗口3卖了一张票,剩余票数为41 窗口2卖了一张票,剩余票数为40 窗口2卖了一张票,剩余票数为39 窗口2卖了一张票,剩余票数为38 窗口2卖了一张票,剩余票数为37 窗口2卖了一张票,剩余票数为36 窗口2卖了一张票,剩余票数为35 窗口2卖了一张票,剩余票数为34 窗口2卖了一张票,剩余票数为33 窗口2卖了一张票,剩余票数为32 窗口2卖了一张票,剩余票数为31 窗口2卖了一张票,剩余票数为30 窗口3卖了一张票,剩余票数为29 窗口3卖了一张票,剩余票数为28 窗口3卖了一张票,剩余票数为27 窗口3卖了一张票,剩余票数为26 窗口3卖了一张票,剩余票数为25 窗口1卖了一张票,剩余票数为24 窗口1卖了一张票,剩余票数为23 窗口1卖了一张票,剩余票数为22 窗口1卖了一张票,剩余票数为21 窗口1卖了一张票,剩余票数为20 窗口1卖了一张票,剩余票数为19 窗口1卖了一张票,剩余票数为18 窗口1卖了一张票,剩余票数为17 窗口3卖了一张票,剩余票数为16 窗口3卖了一张票,剩余票数为15 窗口3卖了一张票,剩余票数为14 窗口3卖了一张票,剩余票数为13 窗口3卖了一张票,剩余票数为12 窗口3卖了一张票,剩余票数为11 窗口2卖了一张票,剩余票数为10 窗口3卖了一张票,剩余票数为9 窗口3卖了一张票,剩余票数为8 窗口3卖了一张票,剩余票数为7 窗口3卖了一张票,剩余票数为6 窗口3卖了一张票,剩余票数为5 窗口3卖了一张票,剩余票数为4 窗口3卖了一张票,剩余票数为3 窗口3卖了一张票,剩余票数为2 窗口3卖了一张票,剩余票数为1 窗口3卖了一张票,剩余票数为0 窗口3没票了 窗口1没票了 窗口2没票了
你每个线程只执行了一次呀思密达。你的关注点只落在锁上了,忽略了每个线程要去循环执行呀。
public void run() {
while(true){
synchronized(lock){
while(ticket<=0){
System.out.println(Thread.currentThread().getName()+
"while剩余"+ticket+"张票");
try {
lock.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName()+
"卖出了一张票,剩余"+(--ticket)+"张票");
lock.notifyAll();
}
}
}