一、sychronized
在 java 中,每个对象都有一个对象监视器,或者说对象锁。 synchronized(obj) 是尝试获取对象obj的对象锁,只有成功获取对象锁后,线程才能执行 synchronized 作用的代码,否则线程会处于 BLOCK 状态。由于对象锁是一个独占锁,所以在同一时刻,只有一个线程能够成功获取对象锁。
sychronized 作用说明:
当线程访问“对象”的 sychronized 的方法或者代码块时,其他线程无法同时访问该方法或者代码块,也无法访问该“对象”的其他sychronized 方法或者代码,但是可以访问该“对象”的非 syhronized 方法或者代码,并且也可以访问其他“对象”的方法或者代码块。
上述说明中,“对象”是指 sychronized 需要获取对象锁的对象。
总之,获取同一个对象锁的 synchronized 互斥。
sychronized 实例方法和静态方法,分别获取实例对象和类对象的对象锁。
二、示例
public class SychronizedDemo {
private int age = 10;
private static String name = "isen";
private synchronized int getAge(){
System.out.println(Thread.currentThread().getName() + " 成功获取 SychronizedDemo 的实例对象的对象锁,进入getAge()方法");
try {
Thread.sleep(1500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " 退出getAge()方法");
return age;
}
private synchronized void setAge(int age){
System.out.println(Thread.currentThread().getName() + " 成功获取 SychronizedDemo 的实例对象的对象锁,进入setAge()方法");
try {
Thread.sleep(1500);
} catch (InterruptedException e) {
e.printStackTrace();
}
this.age = age;
System.out.println(Thread.currentThread().getName() + " 退出setAge()方法");
}
private void printAge(){
System.out.println(Thread.currentThread().getName() + " 进入printAge()方法");
synchronized (this){
try {
Thread.sleep(1500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " 成功获取 SychronizedDemo 的实例对象的对象锁,进入synchronized (this)代码块");
System.out.println("age = " + age);
}
System.out.println(Thread.currentThread().getName() + " 退出printAge()方法");
}
private synchronized static String getName(){
System.out.println(Thread.currentThread().getName() + " 成功获取 SychronizedDemo 的类对象的对象锁,进入getName()方法");
try {
Thread.sleep(1500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " 退出getName()方法");
return name;
}
private synchronized static void setName(String name){
System.out.println(Thread.currentThread().getName() + " 成功获取 SychronizedDemo 的类对象的对象锁,进入setName()方法");
try {
Thread.sleep(1500);
} catch (InterruptedException e) {
e.printStackTrace();
}
SychronizedDemo.name = name;
System.out.println(Thread.currentThread().getName() + " 退出setName()方法");
}
private static void printName(){
System.out.println(Thread.currentThread().getName() + " 进入printName()方法");
synchronized (SychronizedDemo.class){
try {
Thread.sleep(1500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " 成功获取 SychronizedDemo 的类对象的对象锁,进入printName()方法");
System.out.println("name = " + name);
}
System.out.println(Thread.currentThread().getName() + " 退出printName()方法");
}
private void catAge(){
System.out.println(Thread.currentThread().getName() + " 进入catAge()方法");
try {
Thread.sleep(1500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " 退出catAge()方法");
}
private static void catName(){
System.out.println(Thread.currentThread().getName() + " 进入catName()方法");
try {
Thread.sleep(1500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " 退出catName()方法");
}
public static void main(String[] args) {
SychronizedDemo sychronizedDemo = new SychronizedDemo();
new Thread(){
@Override
public void run() {
sychronizedDemo.getAge();
}
}.start();
new Thread(){
@Override
public void run() {
sychronizedDemo.setAge(12);
}
}.start();
new Thread(){
@Override
public void run() {
sychronizedDemo.printAge();
}
}.start();
new Thread(){
@Override
public void run() {
SychronizedDemo.getName();
}
}.start();
new Thread(){
@Override
public void run() {
SychronizedDemo.setName("lisi");
}
}.start();
new Thread(){
@Override
public void run() {
SychronizedDemo.printName();
}
}.start();
new Thread(){
@Override
public void run() {
sychronizedDemo.catAge();
}
}.start();
new Thread(){
@Override
public void run() {
SychronizedDemo.catName();
}
}.start();
}
}