public class Thread2 { AtomicInteger i = new AtomicInteger(10); public synchronized void m4t1() { while (i.get() > 0) { System.out.println(Thread.currentThread().getName() + " : " + i); i.decrementAndGet(); try { Thread.sleep(1000); } catch (InterruptedException ie) { } } } public void m4t2() { synchronized (i) { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } while (i.get() > 0) { System.out.println(Thread.currentThread().getName() + " : " + i); i.decrementAndGet(); try { Thread.sleep(1000); } catch (InterruptedException ie) { } } } } public static void main(String[] args) { final Thread2 myt2 = new Thread2(); Thread t1 = new Thread(new Runnable() { @Override public void run() { myt2.m4t1(); } }, "t1"); Thread t2 = new Thread(new Runnable() { @Override public void run() { myt2.m4t2(); } }, "t2"); t1.start(); t2.start(); } }
运行结果为:
t1 : 10
t1 : 9
t2 : 9
t1 : 7
t2 : 7
t2 : 5
t1 : 5
t2 : 3
t1 : 3
t2 : 1
t1 : 1
原因是程序代码中用到了两个不同的锁,导致程序之间错乱:synchronized void m4t1()要获取的是方法锁、synchronized (i)是块锁,两者不相关,所以会错乱执行。
代码方式二
public class Thread2 { AtomicInteger i = new AtomicInteger(10); public void m4t1() { synchronized (this){ while (i.get() > 0) { System.out.println(Thread.currentThread().getName() + " : " + i); i.decrementAndGet(); try { Thread.sleep(1000); } catch (InterruptedException ie) { } } } } public void m4t2() { synchronized (i) { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } while (i.get() > 0) { System.out.println(Thread.currentThread().getName() + " : " + i); i.decrementAndGet(); try { Thread.sleep(1000); } catch (InterruptedException ie) { } } } } public static void main(String[] args) { final Thread2 myt2 = new Thread2(); Thread t1 = new Thread(new Runnable() { @Override public void run() { myt2.m4t1(); } }, "t1"); Thread t2 = new Thread(new Runnable() { @Override public void run() { myt2.m4t2(); } }, "t2"); t1.start(); t2.start(); } }
结果是:
t1 : 10
t2 : 9
t1 : 9
t2 : 7
t1 : 7
t1 : 5
t2 : 5
t1 : 3
t2 : 3
t2 : 1
t1 : 1
在代码中可以看到synchronized (this)和synchronized (i)也是不同的两个锁,所以两个线程分别获取两个不同的锁,并不会有线程会因为获取不到想要的锁而进行阻塞。
正确代码:
AtomicInteger i = new AtomicInteger(10); public void m4t1() { synchronized (i){ while (i.get() > 0) { System.out.println(Thread.currentThread().getName() + " : " + i); i.decrementAndGet(); try { Thread.sleep(1000); } catch (InterruptedException ie) { } } } } public void m4t2() { synchronized (i) { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } while (i.get() > 0) { System.out.println(Thread.currentThread().getName() + " : " + i); i.decrementAndGet(); try { Thread.sleep(1000); } catch (InterruptedException ie) { } } } } public static void main(String[] args) { final Thread2 myt2 = new Thread2(); Thread t1 = new Thread(new Runnable() { @Override public void run() { myt2.m4t1(); } }, "t1"); Thread t2 = new Thread(new Runnable() { @Override public void run() { myt2.m4t2(); } }, "t2"); t1.start(); t2.start(); } }
结果为:
t1 : 10
t1 : 9
t1 : 8
t1 : 7
t1 : 6
t1 : 5
t1 : 4
t1 : 3
t1 : 2
t1 : 1
两个线程都是要获取synchronized (i)的锁,所以都会进行等待。