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都是处于可执行状态