前面一篇,我们知道了synchronized关键字扩起来范围的代码块就可以实现同步,其实,在Java中,只需要在方法上加上synchronized关键字即可,就像加上static一样。本篇来看看加上synchronized关键字修饰的非静态和静态方法的同步锁对象是什么。
1.非静态同步锁对象是this
复制前面一篇代码,修改如下。
package thread;
public class Demo2_Sync {
public static void main(String[] args) {
final printer p = new printer();
new Thread() {
public void run(){
while(true) {
p.print1();
}
}
}.start();
new Thread() {
public void run(){
while(true) {
p.print2();
}
}
}.start();
}
}
class printer {
public synchronized void print1() {
System.out.print("A");
System.out.print("n");
System.out.print("t");
System.out.print("h");
System.out.print("o");
System.out.print("n");
System.out.print("y");
System.out.print("\r\n");
}
public void print2() {
synchronized(this) {
System.out.print("learn");
System.out.print("Java");
System.out.print("\r\n");
}
}
}
在print1()和print2()方法中同步锁对象要保持一致,那么print2里面同步锁对象就填this,运行测试一看,确实同步。当然,这里你可以保留print2方法传入一个object对象O,测试下看看是不是同步效果。
2.静态同步锁对象是字节码
上面证明了非静态同步锁对象就是this,那么静态同步的对象又是什么,因为静态方法中不能使用this,在静态方法加载的对象是字节码对象,那么这个字节码对象是不是就是锁对象呢,下面来测试一下。
package thread;
public class Demo2_Sync {
public static void main(String[] args) {
final printer p = new printer();
new Thread() {
public void run(){
while(true) {
p.print1();
}
}
}.start();
new Thread() {
public void run(){
while(true) {
p.print2();
}
}
}.start();
}
}
class printer {
public static synchronized void print1() {
System.out.print("A");
System.out.print("n");
System.out.print("t");
System.out.print("h");
System.out.print("o");
System.out.print("n");
System.out.print("y");
System.out.print("\r\n");
}
public static void print2() {
synchronized(Demo2_Sync.class) {
System.out.print("learn");
System.out.print("Java");
System.out.print("\r\n");
}
}
}
注意print2里面同步锁对象是当前类的字节码对象,运行一下,确实有同步效果,结论就是,静态方法中,多线程同步锁对象就是当前类的字节码对象。