使用synchronized锁的时候,作为锁的对象最好要加上final修饰符,因为可能线程会改变锁变量持有的具体的对象。demo如下:
public class Test02 {
static Object lock = new Object();
public static void main(String[] args) {
Thread t1 = new Thread(() -> {
lock = new Object();
synchronized (lock) {
for (int i = 0; i < 10; i++) {
try {
Thread.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("A");
}
}
});
Thread t2 = new Thread(() -> {
lock = new Object();
synchronized (lock) {
for (int i = 0; i < 10; i++) {
try {
Thread.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("B");
}
}
});
t1.start();
t2.start();
}
}
上述程序的打印输出为:
A
B
A
B
A
B
A
B
A
B
A
B
A
B
A
B
A
B
A
B
但是要是把锁改成final的。代码如下:
public class Test02 {
static final Object lock = new Object();
public static void main(String[] args) {
Thread t1 = new Thread(() -> {
// lock = new Object(); // 编译出错,final不能修改
synchronized (lock) {
for (int i = 0; i < 10; i++) {
try {
Thread.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("A");
}
}
});
Thread t2 = new Thread(() -> {
// lock = new Object();
synchronized (lock) {
for (int i = 0; i < 10; i++) {
try {
Thread.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("B");
}
}
});
t1.start();
t2.start();
}
}
打印的结果为:
A
A
A
A
A
A
A
A
A
A
B
B
B
B
B
B
B
B
B
B
综述,以后锁对象加final修饰。