java多线程售票小例子
java多线程售票小例子
1、错误示范
class SellThread implements Runnable { private int i = 20; public void run() { while(true) { if(i > 0) { try { Thread.sleep(100); } catch(Exception e) { } System.out.println(Thread.currentThread().getName() + "sell " + i--); } } } } public class Test { public static void main(String[] args) { SellThread sell = new SellThread(); Thread sell1 = new Thread(sell, "sellman1"); Thread sell2 = new Thread(sell, "sellman2"); Thread sell3 = new Thread(sell, "sellman3"); sell1.start(); sell2.start(); sell3.start(); } }
没有同步控制变量,所以最后出现了-1张票
2、正确示范
class SellThread implements Runnable { private int i = 20; String key = ""; public void run() { while(true) { synchronized(key) { if(i > 0) { try { Thread.sleep(100); } catch(Exception e) { } System.out.println(Thread.currentThread().getName() + "sell " + i--); }else { break; } } } } } public class Test { public static void main(String[] args) { SellThread sell = new SellThread(); Thread sell1 = new Thread(sell, "sellman1"); Thread sell2 = new Thread(sell, "sellman2"); Thread sell3 = new Thread(sell, "sellman3"); sell1.start(); sell2.start(); sell3.start(); } }
补充:如果用synchronized关键字修饰方法,则只能有一个线程获取访问这段方法的权限。也就是说,一个线程把票买完了才结束。
class SellThread implements Runnable { private int i = 20; String key = ""; public synchronized void run() { while(true) { if(i > 0) { try { Thread.sleep(100); } catch(Exception e) { } System.out.println(Thread.currentThread().getName() + "sell " + i--); }else { break; } } } } public class Test { public static void main(String[] args) { SellThread sell = new SellThread(); Thread sell1 = new Thread(sell, "sellman1"); Thread sell2 = new Thread(sell, "sellman2"); Thread sell3 = new Thread(sell, "sellman3"); sell1.start(); sell2.start(); sell3.start(); } }
总结:
1、synchronized()括号中需要的是一个对象,所以这里使用了String类的一个对象key,可以用this来代替key。
2、一个线程拿到synchronized括号中的对象以后,其他线程也是可以执行的,但是当它们需要用key的时候,发现key已经被别人拿走了,只能等着key被释放了。就像上厕所,坑被别人占了,只能等着了,但是等着的时候我还可以运行,比如玩玩手机什么的。
3、synchronized method(){} 可以防止多个线程同时访问这个对象的synchronized方法;如果一个对象A,有多个synchronized方法,只要一个线程访问了其中的一个,那么其他线程不能同时访问A的任何一个synchronized方法。但是可以访问对象B的synchronized方法。
4、synchronized static method(){} 可以防止多个线程同时访问这个类的synchronized方法;对类的所有对象均起作用,无论对象A、对象B、对象C的。
关于3、4,请参考
上一篇:
通过多线程提高代码的执行效率例子
下一篇:
用C语言实现猜数字游戏