使用 synchronized 关键字时, 类锁、对象锁的范围
多线程安全方面很多人不是很明了,这是一个测试类,可以直接运行,验证类锁和对象锁;
间接的说明,锁的使用范围。
希望可以帮助到大家
package com.study.synchronize;
/**
* 使用 synchronized 关键字,
* 确定同步安全的作用域,
* 区分类锁还是对象锁
* 1 类锁
* 2 对象锁
*[@zhangmingjie](https://my.oschina.net/zhangmingjie)
*[@date](https://my.oschina.net/u/2504391) 2019-01-20
*/
public class TestSynchronized {
private final Object obj = new Object();
/**
* 对象锁,实例锁
* 在同一实例下,当前方法为同步安全的;
* 如果是多个实例调用此方法,为异步进行
*/
public void instanceObjectLock(){
synchronized (obj){
try {
System.out.println(" 实例对象锁--线程 " + Thread.currentThread().getName() + " 开始等待中:");
Thread.currentThread().sleep(5000l);
System.out.println(" 实例对象锁--线程 " + Thread.currentThread().getName() + " 完成");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
/**
*
* 类锁
* 在同一实例下,当前方法为同步安全的;
* 多个实例下,当前方法也为同步安全的;
*/
public synchronized static void classLock(){
try {
System.out.println(" 类锁---线程 " + Thread.currentThread().getName() + " 开始等待中:");
Thread.currentThread().sleep(5000l);
System.out.println(" 类锁---线程 " + Thread.currentThread().getName() + " 完成");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private static TestSynchronized singleInstance = new TestSynchronized();
public static void main(String[] args) {
/**
* 同一实例下,两个线程同时访问,该方法是同步安全的
*/
for (int i = 0; i < 2 ; i++) {
new Thread(new Runnable() {
[@Override](https://my.oschina.net/u/1162528)
public void run() {
singleInstance.instanceObjectLock();
}
}).start();
}
/**
* 每个线程 new 一个实例,访问 instanceObjectLock 方法是异步不安全的
* 所谓的不安全,如果 instanceObjectLock 方法内访问,全局共享变量,则可能会出现数据的不安全
*/
for (int i = 0; i < 2 ; i++) {
new Thread(new Runnable() {
[@Override](https://my.oschina.net/u/1162528)
public void run() {
TestSynchronized instance = new TestSynchronized();
instance.instanceObjectLock();
}
}).start();
}
/**
* 每个线程 new 一个实例,访问 classLock 方法是同步安全的,
* 一个类只有一把类锁,
* static 修饰的方法是类级别的方法,作用域要比实例高一级
*
* 多个实例访问安全,单一实例访问同样安全
*/
for (int i = 0; i < 2 ; i++) {
new Thread(new Runnable() {
[@Override](https://my.oschina.net/u/1162528)
public void run() {
TestSynchronized test = new TestSynchronized();
test.classLock();
}
}).start();
};
}
}