public void add(String status) {
System.out.println(“add status:” + status);
}
}
这个例子中,没有对外暴露修改name字段的入口,所以不存在线程安全问题。
3\. synchronized
----------------
使用`JDK`内部提供的`同步机制`,这也是使用比较多的手段,分为:`同步方法` 和 `同步代码块`。
我们优先使用同步代码块,因为同步方法的粒度是整个方法,范围太大,相对来说,更消耗代码的性能。
其实,每个对象内部都有一把`锁`,只有抢到那把锁的`线程`,才被允许进入对应的代码块执行相应的代码。
当代码块执行完之后,JVM底层会自动释放那把锁。
例如:
public class SyncService {
private int age = 1;
private Object object = new Object();
//同步方法
public synchronized void add(int i) {
age = age + i;
System.out.println(“age:” + age);
}
public void update(int i) {
//同步代码块,对象锁
synchronized (object) {
age = age + i;
System.out.println(“age:” + age);
}
}
public void update(int i) {
//同步代码块,类锁
synchronized (SyncService.class) {
age = age + i;
System.out.println(“age:” + age);
}
}
}
4\. Lock
--------
除了使用`synchronized`关键字实现同步功能之外,JDK还提供了`Lock`接口,这种显示锁的方式。
通常我们会使用`Lock`接口的实现类:`ReentrantLock`,它包含了:`公平锁`、`非公平锁`、`可重入锁`、`读写锁` 等更多更强大的功能。
例如:
public class LockService {
private ReentrantLock reentrantLock = new ReentrantLock();
public int age = 1;
public void add(int i) {
try {
reentrantLock.lock();
age = age + i;
System.out.println(“age:” + age);
} finally {
reentrantLock.unlock();
}
}
}
但如果使用ReentrantLock,它也带来了有个小问题就是:`需要在finally代码块中手动释放锁`。
不过说句实话,在使用`Lock`显示锁的方式,解决线程安全问题