第一种写法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | public class SyncTest { public synchronized void synMethod1(String key) { // (*) System.out.println(key + " ==> " + Thread.currentThread().toString()); try { Thread.sleep(Long.MAX_VALUE); } catch (InterruptedException e) { e.printStackTrace(); } } public static void main(String[] args) { final SyncTest st1 = new SyncTest(); Thread a1 = new Thread(new Runnable() { @Override public void run() { st1.synMethod1("No.1"); } }); a1.start(); Thread a2 = new Thread(new Runnable() { @Override public void run() { st1.synMethod1("No.2"); } }); a2.start(); } } |
输出为:
No.1 ==> Thread[Thread-0,5,main]
去除synchronized关键字,输出变为:
No.1 ==> Thread[Thread-0,5,main] No.2 ==> Thread[Thread-1,5,main]
说明:标为synchronized的方法,进入后会把本对象锁住,其他线程无法进入任何非静态synchronized区域。
第二种写法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | public class SyncTest { public void synMethod2(String key, Object lock) { System.out.println(key + " ==> I'm In. "); synchronized (lock) { // (*) try { System.out.println(key + " ==> " + Thread.currentThread().toString()); Thread.sleep(Long.MAX_VALUE); } catch (InterruptedException e) { e.printStackTrace(); } } } public static void main(String[] args) { final SyncTest st1 = new SyncTest(); final Object lock = new Object(); // (*) Thread a1 = new Thread(new Runnable() { @Override public void run() { st1.synMethod2("No.1", lock); } }); a1.start(); Thread a2 = new Thread(new Runnable() { @Override public void run() { st1.synMethod2("No.2", lock); } }); a2.start(); } } |
输出为:
No.1 ==> I'm In. No.1 ==> Thread[Thread-0,5,main] No.2 ==> I'm In.
修改synchronized(lock)为synchronized(key),输出变为:
No.1 ==> I'm In. No.1 ==> Thread[Thread-0,5,main] No.2 ==> I'm In. No.2 ==> Thread[Thread-1,5,main]
说明:标为synchronized(object)的块,当object一样时,只有一个线程能够进入。
第三种写法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | public class SyncTest { public void synMethod3(String key) { System.out.println(key + " ==> I'm In. "); synchronized (this) { // (*) try { System.out.println(key + " ==> " + Thread.currentThread().toString()); Thread.sleep(Long.MAX_VALUE); } catch (InterruptedException e) { e.printStackTrace(); } } } public static void main(String[] args) { final SyncTest st1 = new SyncTest(); Thread a1 = new Thread(new Runnable() { @Override public void run() { st1.synMethod3("No.1"); } }); final SyncTest st2 = new SyncTest(); a1.start(); Thread a2 = new Thread(new Runnable() { @Override public void run() { st1.synMethod3("No.2"); // (*) } }); a2.start(); } } |
输出为:
No.1 ==> I'm In. No.1 ==> Thread[Thread-0,5,main] No.2 ==> I'm In.
修改第26行的st1为st2,输出变为:
No.1 ==> I'm In. No.1 ==> Thread[Thread-0,5,main] No.2 ==> I'm In. No.2 ==> Thread[Thread-1,5,main]
说明:
1、synchronized(this)其实就是synchronized(Object),只不过object传入了自己。
2、第一种写法中,对方法的synchronized声明,实际上等于对方法中所有代码的synchronized(this){}包裹。
第四种写法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | public class SyncTest { public static String SSS = "static access"; // (*) public static void synMethod4(String key) { System.out.println(key + " ==> I'm In. "); synchronized (SyncTest.class) { // (*) try { System.out.println(key + " ==> " + Thread.currentThread().toString()); Thread.sleep(Long.MAX_VALUE); } catch (InterruptedException e) { e.printStackTrace(); } } } public synchronized static void synMethod5(String key) { // (*) System.out.println(key + " ==> I'm In synMethod5. "); try { Thread.sleep(Long.MAX_VALUE); } catch (InterruptedException e) { e.printStackTrace(); } } public static void main(String[] args) throws Exception { Thread a1 = new Thread(new Runnable() { @Override public void run() { System.out.println("No.1 ==> " + SyncTest.SSS); SyncTest.synMethod4("No.1"); // (*) } }); a1.start(); Thread a2 = new Thread(new Runnable() { @Override public void run() { System.out.println("No.2 ==> " + SyncTest.SSS); SyncTest.synMethod5("No.2"); // (*) } }); Thread.sleep(1000); a2.start(); } } <strong>输出为:</strong> |
No.1 ==> static access No.1 ==> I'm In. No.1 ==> Thread[Thread-0,5,main] No.2 ==> static access
将22行和30行的4和5对换,输出变为:
No.1 ==> static access No.1 ==> I'm In synMethod5. No.2 ==> static access No.2 ==> I'm In.
说明:
1、类中synchronized(clasz)块的锁,可以阻止static方法的访问,但不影响static feild变量的访问。
2、类中static synchronized方法的锁,也会影响synchronized(clasz)块
纯属实验,若有错误,欢迎指正。