分类
类锁:在代码中的方法上加了static和synchronized的锁,或者synchronized(xxx.class)的代码段。
对象锁:在代码中的方法上加了synchronized的锁,或者synchronized(this)的代码段。
代码
package com.example.shengshuqiang.helloworld;
/**
* User: shengshuqiang
* Date: 2015-08-31
* Time: 15:25
*/
public class JavaTest {
public static void main(String[] args) {
Object lock = new Object();
for (int i = 0; i < 5; i++) {
System.out.println(i);
new TestClassLockThread().start();
new TestObjectLockThread().start();
new TestOneObjectLockThread(lock).start();
}
}
static class A {
public static synchronized void classLock() {
System.out.println("classLock start");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("classLock end");
}
public synchronized void objectLock() {
System.out.println(this + "objectLock start");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(this + "objectLock end");
}
public void oneObjectLock(Object lock) {
synchronized (lock) {
System.out.println(this + ", lock= " + lock + ", oneObjectLock start");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(this + ", lock= " + lock + ", oneObjectLock end");
}
}
}
static class TestClassLockThread extends Thread {
@Override
public void run() {
A.classLock();
}
}
static class TestObjectLockThread extends Thread {
@Override
public void run() {
A a = new A();
a.objectLock();
}
}
static class TestOneObjectLockThread extends Thread {
private Object lock;
public TestOneObjectLockThread(Object lock) {
this.lock = lock;
}
@Override
public void run() {
A a = new A();
a.oneObjectLock(lock);
}
}
}
输出
0
classLock start
com.example.shengshuqiang.helloworld.JavaTest$A@7461e6f7objectLock start
1
com.example.shengshuqiang.helloworld.JavaTest$A@72116e25, lock= java.lang.Object@7cd68e17, oneObjectLock start
2
com.example.shengshuqiang.helloworld.JavaTest$A@69ab3312objectLock start
3
com.example.shengshuqiang.helloworld.JavaTest$A@47420a89objectLock start
4
com.example.shengshuqiang.helloworld.JavaTest$A@3ff76fb9objectLock start
com.example.shengshuqiang.helloworld.JavaTest$A@20fc4b96objectLock start
classLock end
com.example.shengshuqiang.helloworld.JavaTest$A@72116e25, lock= java.lang.Object@7cd68e17, oneObjectLock end
com.example.shengshuqiang.helloworld.JavaTest$A@7461e6f7objectLock end
com.example.shengshuqiang.helloworld.JavaTest$A@69ab3312objectLock end
com.example.shengshuqiang.helloworld.JavaTest$A@20fc4b96objectLock end
com.example.shengshuqiang.helloworld.JavaTest$A@47420a89objectLock end
com.example.shengshuqiang.helloworld.JavaTest$A@3ff76fb9objectLock end
com.example.shengshuqiang.helloworld.JavaTest$A@615608be, lock= java.lang.Object@7cd68e17, oneObjectLock start
classLock start
classLock end
com.example.shengshuqiang.helloworld.JavaTest$A@615608be, lock= java.lang.Object@7cd68e17, oneObjectLock end
classLock start
com.example.shengshuqiang.helloworld.JavaTest$A@694f64d2, lock= java.lang.Object@7cd68e17, oneObjectLock start
classLock end
com.example.shengshuqiang.helloworld.JavaTest$A@694f64d2, lock= java.lang.Object@7cd68e17, oneObjectLock end
classLock start
com.example.shengshuqiang.helloworld.JavaTest$A@286b2962, lock= java.lang.Object@7cd68e17, oneObjectLock start
classLock end
com.example.shengshuqiang.helloworld.JavaTest$A@286b2962, lock= java.lang.Object@7cd68e17, oneObjectLock end
classLock start
com.example.shengshuqiang.helloworld.JavaTest$A@5922fa5a, lock= java.lang.Object@7cd68e17, oneObjectLock start
classLock end
com.example.shengshuqiang.helloworld.JavaTest$A@5922fa5a, lock= java.lang.Object@7cd68e17, oneObjectLock end
classLock start
com.example.shengshuqiang.helloworld.JavaTest$A@7461e6f7objectLock start
1
com.example.shengshuqiang.helloworld.JavaTest$A@72116e25, lock= java.lang.Object@7cd68e17, oneObjectLock start
2
com.example.shengshuqiang.helloworld.JavaTest$A@69ab3312objectLock start
3
com.example.shengshuqiang.helloworld.JavaTest$A@47420a89objectLock start
4
com.example.shengshuqiang.helloworld.JavaTest$A@3ff76fb9objectLock start
com.example.shengshuqiang.helloworld.JavaTest$A@20fc4b96objectLock start
classLock end
com.example.shengshuqiang.helloworld.JavaTest$A@72116e25, lock= java.lang.Object@7cd68e17, oneObjectLock end
com.example.shengshuqiang.helloworld.JavaTest$A@7461e6f7objectLock end
com.example.shengshuqiang.helloworld.JavaTest$A@69ab3312objectLock end
com.example.shengshuqiang.helloworld.JavaTest$A@20fc4b96objectLock end
com.example.shengshuqiang.helloworld.JavaTest$A@47420a89objectLock end
com.example.shengshuqiang.helloworld.JavaTest$A@3ff76fb9objectLock end
com.example.shengshuqiang.helloworld.JavaTest$A@615608be, lock= java.lang.Object@7cd68e17, oneObjectLock start
classLock start
classLock end
com.example.shengshuqiang.helloworld.JavaTest$A@615608be, lock= java.lang.Object@7cd68e17, oneObjectLock end
classLock start
com.example.shengshuqiang.helloworld.JavaTest$A@694f64d2, lock= java.lang.Object@7cd68e17, oneObjectLock start
classLock end
com.example.shengshuqiang.helloworld.JavaTest$A@694f64d2, lock= java.lang.Object@7cd68e17, oneObjectLock end
classLock start
com.example.shengshuqiang.helloworld.JavaTest$A@286b2962, lock= java.lang.Object@7cd68e17, oneObjectLock start
classLock end
com.example.shengshuqiang.helloworld.JavaTest$A@286b2962, lock= java.lang.Object@7cd68e17, oneObjectLock end
classLock start
com.example.shengshuqiang.helloworld.JavaTest$A@5922fa5a, lock= java.lang.Object@7cd68e17, oneObjectLock start
classLock end
com.example.shengshuqiang.helloworld.JavaTest$A@5922fa5a, lock= java.lang.Object@7cd68e17, oneObjectLock end
结论
锁的本质是判断是否锁住同一个东西,如果竞争的是同一个锁,则互斥。如果不是同一个锁,则相互不影响。
类锁是锁住该类,全局只有一个类A,所以线程对该类的锁获取是互斥的。一定是先输出“class lock start”,然后“class lock end”,即执行“class lock start”后,别的线程需要等待该方法执行完“class lock end”,才可以接着执行。必须要等到类A的锁释放后才可以重新获取。
对象锁是锁住该对象,
如果竞争的不是同一个对象,则对象锁的获取相互不影响。上面输出可以看出,连续两个
“object lock start”对应的对象this不一样。
如果竞争的是同一个对象,则对象锁的获取互斥。上面输出可以看出,“oneObject lock start”“oneObject lock end”顺序出行,在执行“oneObject lock start”后,想要获取该对象锁lock的其他线程必须等待lock锁释放后“oneObject lock end”
参考链接
http://ifeve.com/java-locks/