synchronized 方法控制对类成员变量的访问:每个类实例对应一把锁,每个 synchronized 方法都必须获得调用该方法的类实例的锁方能执行,否则所属线程阻塞,方法一旦执行,就独占该锁,直到从该方法返回时才将锁释放,此后被阻塞的线程方能获得该锁,重新进入可执行状态。这种机制确保了同一时刻对于每一个类实例,其所有声明为 synchronized 的成员函数中至多只有一个处于可执行状态(因为至多只有一个能够获得该类实例对应的锁),从而有效避免了类成员变量的访问冲突(只要所有可能访问类成员变量的方法均被声明为 synchronized)。
举例如下:
①同一个对象中的两个线程(function1和function2作为普通方法)
package co.test.synchronize; public class Test implements Runnable { private int count = 0; public Test(int whichThread) { count = whichThread; } public static void main(String[] args) { // 同一个对象中的两个线程-----------------------↓ Test test = new Test(0); Thread thread1 = new Thread(test); thread1.start(); Thread thread2 = new Thread(test); thread2.start(); // 同一个对象中的两个线程-----------------------↑ } @Override public void run() { if (count == 0) { function1(); } else { function2(); } } private void function1() { count = 1; System.out.println("function11111 is start"); try { // 模拟耗时操作 Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("function11111 is end"); } private void function2() { System.out.println("function22222 is start"); System.out.println("function22222 is end"); } }
执行结果:
function11111 is start function22222 is start function22222 is end function11111 is end
function1和function2都是处于可执行状态
②同一个对象中的两个线程(function1和function2均被声明为 synchronized)
package co.test.synchronize; public class Test implements Runnable { private int count = 0; public Test(int whichThread) { count = whichThread; } public static void main(String[] args) { // 同一个对象中的两个线程-----------------------↓ Test test = new Test(0); Thread thread1 = new Thread(test); thread1.start(); Thread thread2 = new Thread(test); thread2.start(); // 同一个对象中的两个线程-----------------------↑ } @Override public void run() { if (count == 0) { function1(); } else { function2(); } } private synchronized void function1() { count = 1; System.out.println("function11111 is start"); try { // 模拟耗时操作 Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("function11111 is end"); } private synchronized void function2() { System.out.println("function22222 is start"); System.out.println("function22222 is end"); } } 执行结果:
function11111 is start function11111 is end function22222 is start function22222 is end
function2等function1执行完之后才被执行
③两个对象中的两个线程(function1和function2作为普通方法)
package co.test.synchronize; public class Test implements Runnable { private int count = 0; public Test(int whichThread) { count = whichThread; } public static void main(String[] args) { // 两个对象中的两个线程-----------------------↓ Test test1 = new Test(0); Test test2 = new Test(1); Thread thread1 = new Thread(test1); thread1.start(); Thread thread2 = new Thread(test2); thread2.start(); // 两个对象中的两个线程-----------------------↑ } @Override public void run() { if (count == 0) { function1(); } else { function2(); } } private void function1() { count = 1; System.out.println("function11111 is start"); try { // 模拟耗时操作 Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("function11111 is end"); } private void function2() { System.out.println("function22222 is start"); System.out.println("function22222 is end"); } }
执行结果:
function11111 is start function22222 is start function22222 is end function11111 is end
function1和function2都是处于可执行状态
④两个对象中的两个线程(function1和function2均被声明为 synchronized)
package co.test.synchronize; public class Test implements Runnable { private int count = 0; public Test(int whichThread) { count = whichThread; } public static void main(String[] args) { // 两个对象中的两个线程-----------------------↓ Test test1 = new Test(0); Test test2 = new Test(1); Thread thread1 = new Thread(test1); thread1.start(); Thread thread2 = new Thread(test2); thread2.start(); // 两个对象中的两个线程-----------------------↑ } @Override public void run() { if (count == 0) { function1(); } else { function2(); } } private synchronized void function1() { count = 1; System.out.println("function11111 is start"); try { // 模拟耗时操作 Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("function11111 is end"); } private synchronized void function2() { System.out.println("function22222 is start"); System.out.println("function22222 is end"); } } 执行结果:
function11111 is start function22222 is start function22222 is end function11111 is end
function1和function2都是处于可执行状态