在Java中,synchronized 关键字用于实现线程之间的同步。提供了一种简单而强大的机制来控制多个线程之间的并发访问,确保共享资源的安全性和一致性。它解决了多线程环境中的竞态条件、数据竞争和内存模型等问题,是实现线程安全的重要手段之一。它主要有以下几个作用:
synchronized 是 Java 中用于实现内置锁(Intrinsic Lock)或监视器锁(Monitor Lock)的关键字,它属于独占锁(Exclusive Lock)或互斥锁(Mutual Exclusion Lock)。
使用时有以下几点注意
作用在代码上,相当于给代码块加锁(Lock)
public void performTask() {
// synchronized 作用于代码块
synchronized (lock) {
// 业务逻辑,同步代码块,对共享资源进行操作
}
}
作用在方法上,相当于给整个方法加锁(Lock)
// synchronized 作用在方法上
public synchronized void increment() {
// 业务逻辑,同步代码块,对共享资源进行操作
}
一个会出异常的示例
package top.yiqifu.study.p004_thread;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
public class Test061_ThreadSynchronized {
public static class Counter {
private volatile int count = 0;
public void increment() {
count++;
}
public int getCount() {
return count;
}
public void add(){
if(this.getCount() < 50000){
// Thread.yield();
File.listRoots();// 模拟复杂业务,执行一些额外的语句
this.increment();
}
}
}
public static void main(String[] args) {
Counter counter = new Counter();
List<Thread> threads = new ArrayList<>();
for(int count = 0; count < 100; count++) {
Thread thread = new Thread(() -> {
for (int i = 0; i < 1000; i++) {
counter.add();
}
});
threads.add(thread);
}
for(Thread t : threads) {
t.start();
}
for(Thread t : threads) {
try {
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("最后结果: " + counter.getCount());
}
}
修改正示例
要解决这个问题,可以使用 synchronized 关键字来对代码块加锁。
在代码块上加 synchronized 关键字
public void add(){
synchronized(this) {
if(this.getCount() < 50000){
File.listRoots();// 模拟复杂业务,执行一些额外的语句
this.increment();
}
}
}
在 add 方法上加 synchronized 关键字
public synchronized void add(){
if(this.getCount() < 50000){
File.listRoots();// 模拟复杂业务,执行一些额外的语句
this.increment();
}
}