Java 多线程售票
方式一:继承thread 类
每个线程100张票
package com.example.starter;public class SellTickets extends Thread{public static void main(String[] args) {Thread t1 = new SellTick1();Thread t2 = new SellTick1();Thread t3 = new SellTick1();t1.start();t2.start();t3.start();}
}class SellTick1 extends Thread{private int num = 100;@Overridepublic void run(){while(true){if(num <= 0){System.out.println("售票结束");break;}try {Thread.sleep(50);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("窗口"+Thread.currentThread().getName()+ "售出 一张票 剩余票数=" + (--num ));}}
}
结果:

方式二:num 使用static修饰
一共100张票 有重复减票的情况,最后还有减成负数的情况
package com.example.starter;public class SellTickets extends Thread{public static void main(String[] args) {Thread t1 = new SellTick1();Thread t2 = new SellTick1();Thread t3 = new SellTick1();t1.start();t2.start();t3.start();}
}class SellTick1 extends Thread{private static int num = 100;@Overridepublic void run(){while(true){if(num <= 0){System.out.println("售票结束");break;}try {Thread.sleep(50);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("窗口"+Thread.currentThread().getName()+ "售出 一张票 剩余票数=" + (--num));}}
}
结果:


方式三:实现runnable的方式
package com.example.starter;public class SellTickets extends Thread{public static void main(String[] args) {SellTicket2 sellTicket2 = new SellTicket2();Thread t1 = new Thread(sellTicket2);Thread t2 = new Thread(sellTicket2);Thread t3 = new Thread(sellTicket2);t1.start();t2.start();t3.start();}
}class SellTicket2 implements Runnable{private int num = 100;@Overridepublic void run() {while(true){if(num <= 0){System.out.println("售票结束");break;}try {Thread.sleep(50);} catch (InterruptedException e) {e.printStackTrace();}num --;System.out.println("窗口"+Thread.currentThread().getName()+ "售出 一张票 剩余票数=" + (num));}}
}
结果

方式四:以上三种方式多存在多售票的问题,使用synchronized优化
package com.example.starter;public class SellTickets extends Thread{public static void main(String[] args) {SellTicket2 sellTicket2 = new SellTicket2();Thread t1 = new Thread(sellTicket2);Thread t2 = new Thread(sellTicket2);Thread t3 = new Thread(sellTicket2);t1.start();t2.start();t3.start();}
}class SellTicket2 implements Runnable{private volatile int num = 100;private volatile boolean loop = true;@Overridepublic void run() {while(loop){sell();}}synchronized void sell(){if(num <= 0){System.out.println("售票结束");loop = false;return;}num --;System.out.println("窗口"+Thread.currentThread().getName()+ "售出 一张票 剩余票数=" + (num));}
}
结果:

方式五:
package com.example.starter;public class SynSellTickets extends Thread{public static void main(String[] args) {SellTicket3 sellTicket3 = new SellTicket3();Thread t1 = new Thread(sellTicket3);Thread t2 = new Thread(sellTicket3);Thread t3 = new Thread(sellTicket3);t1.start();t2.start();t3.start();}
}class SellTicket3 implements Runnable{private int num = 100;private boolean loop = true;@Overridepublic void run() {while(loop){synchronized (this){if(num > 0){num --;System.out.println("窗口"+Thread.currentThread().getName()+ "售出 一张票 剩余票数=" + (num));}else{loop = false;}}}System.out.println("售票结束");}}
结果:

方式六:使用Lock类
class Resource{private int num = 100;Lock lock = new ReentrantLock();boolean loop = true;public void desStock(){while(loop){lock.lock();try {if(num > 0){num --;System.out.println("窗口"+Thread.currentThread().getName()+ "售出 一张票 剩余票数=" + (num));}else{loop = false;}} catch (Exception e) {e.printStackTrace();}finally {lock.unlock();}}}
}
public class LockSellTickets extends Thread{public static void main(String[] args) {Resource resource = new Resource();new Thread(()->{resource.desStock();},"AA").start();new Thread(()->{resource.desStock();},"BB").start();}
}
打印结果

方式七 atomic加syn
class Resource1{private AtomicInteger at = new AtomicInteger(100);boolean loop = true;public int decStock(){return at.decrementAndGet();}public void sell(){while(loop){synchronized (this){int i = decStock();if(i > 0){System.out.println("窗口"+Thread.currentThread().getName()+ "售出 一张票 剩余票数=" + (i));}else{loop = false;}}}}
}public class AtomicSellTickets extends Thread{public static void main(String[] args) {Resource1 resource = new Resource1();new Thread(()->{resource.sell();},"AA").start();new Thread(()->{resource.sell();},"BB").start();}
}

本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
