synchronized方法

来源:互联网 发布:小蚁摄像头编程 编辑:程序博客网 时间:2024/05/17 11:57


在看多线程这块,突然有个想法,把synchronized关键字直接加到run方法上,会有什么效果。以售票为例,结果就出问题了。

MyRunnable m = new MyRunnable();Thread t1 = new Thread(m,"1");Thread t2 = new Thread(m,"2");Thread t3 = new Thread(m,"3");Thread t4 = new Thread(m,"4");Thread t5 = new Thread(m,"5");t1.start();t2.start();t3.start();t4.start();t5.start();

private int tickets = 2000;@Overridepublic synchronized void run(){while(true){try{if(tickets>0){try {Thread.sleep(5);} catch (Exception e) {e.printStackTrace();}System.err.println("窗口"+Thread.currentThread().getName()+"正在出售第"+(tickets--)+"张票");}}catch(Exception e){e.printStackTrace();}}}
结果:

效果就是只有一个线程执行,其余线程不执行。后来查了一下,被synchronized关键字修饰的方法,任何时候最多只能被一个线程执行。问题应该就出在这里。当一开始其中一个线程抢到执行权后,由于活该方法中有一个while循环一直执行,所以该线程就一直执行,直到结束,退出方法,其他线程才有机会获得执行权,但该例子中此时程序已经执行结束了。一直处于等待状态。


private int tickets = 100;Lock lock = new ReentrantLock();@Overridepublic  void run() {while(true){try{lock.lock();if(tickets>0){try{Thread.sleep(10);}catch(Exception e){e.printStackTrace();}System.err.println("窗口"+Thread.currentThread().getName()+"正在出售第"+(tickets--)+"张票");}}catch (Exception e) {e.printStackTrace();}finally{lock.unlock();}}}

或者:

Object o = new Object();@Overridepublic  void run(){while(true){synchronized(o){try{if(tickets>0){try {Thread.sleep(300);} catch (Exception e) {e.printStackTrace();}System.err.println("窗口"+Thread.currentThread().getName()+"正在出售第"+(tickets--)+"张票");}}catch(Exception e){e.printStackTrace();}}}}

将之前的代码改为上面代码执行就正常了。总之,就是把同步锁加在while循环内就可以了,这样每进行一次while循环,其他线程都有机会获得锁对象。


结果:

由于sleep时间短,效果不是很明显






原创粉丝点击