第一种比较:对象锁与synchronized方法
public class TestSynchronized {
public void test1() {
synchronized (this) {
int i = 5;
while (i-- > 0) {
System.out.println(Thread.currentThread().getName() + " : " + i);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
}
}
}
}
public synchronized void test2() {
int i = 5;
while (i-- > 0) {
System.out.println(Thread.currentThread().getName() + " : " + i);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
}
}
}
public static void main(String[] args) {
final TestSynchronized myt2 = new TestSynchronized();
Thread test1 = new Thread(new Runnable() {
public void run() {
myt2.test1();
}
}, "test1");
Thread test2 = new Thread(new Runnable() {
public void run() {
myt2.test2();
}
}, "test2");
test1.start();
test2.start();
}
}
test1 : 4
test1 : 3
test1 : 2
test1 : 1
test1 : 0
test2 : 4
test2 : 3
test2 : 2
test2 : 1
test2 : 0
从结果看出当synchronized(this)表示获得对象的对象锁,此时其他线程是无法访问同一对象的其他synchronized方法的。因为要访问对象的synchronized方法,那就必须获得当前对象锁。
上述Test2()方法删除synchronized关键字,运行结果如下,说明当synchronized(this)获得对象的对象锁后,其他线程是可以访问同一对象非synchronized方法的
test1 : 4
test2 : 4
test2 : 3
test1 : 3
test2 : 2
test1 : 2
test2 : 1
test1 : 1
test2 : 0
test1 : 0
第二种比较:类锁与static synchronized修饰的方法
public class TestSynchronized {
public void test1() {
synchronized (TestSynchronized.class) {
int i = 5;
while (i-- > 0) {
System.out.println(Thread.currentThread().getName() + " : " + i);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
}
}
}
}
public static synchronized void test2() {
int i = 5;
while (i-- > 0) {
System.out.println(Thread.currentThread().getName() + " : " + i);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
}
}
}
public static void main(String[] args) {
final TestSynchronized myt2 = new TestSynchronized();
Thread test1 = new Thread(new Runnable() {
public void run() {
myt2.test1();
}
}, "test1");
Thread test2 = new Thread(new Runnable() {
public void run() {
myt2.test2();
}
}, "test2");
test1.start();
test2.start();
}
}
test1 : 4
test1 : 3
test1 : 2
test1 : 1
test1 : 0
test2 : 4
test2 : 3
test2 : 2
test2 : 1
test2 : 0
从结果看出synchronized (TestSynchronized.class)获取到类锁的效果和static synchronized修饰的方法效果是一样的,因为所有static方法是所有对象实例共用的。
上述static synchronized void test2()修改为synchronized void test2(),后执行结果如下
test1 : 4
test2 : 4
test1 : 3
test2 : 3
test1 : 2
test2 : 2
test1 : 1
test2 : 1
test1 : 0
test2 : 0
从结果看出类锁与对象锁是不一样的,线程获得对象锁的同时,也可以获得该类锁,即同时获得两个锁,这是允许的。