方案1:synchronized
使用synchronized修饰相关函数,确保某一时刻只有一个增加变量的函数在运行,从而确保了结果的正确性
public class SharedResourceExample {
private static int sharedNumber = 0;
public static void main(String[] args) {
// 创建多个线程进行加法操作
for (int i = 0; i < 5; i++) {
new Thread(() -> {
for (int j = 0; j < 10000; j++) {
incrementSharedNumber();
}
}).start();
}
// 等待所有线程执行完毕
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 输出结果
System.out.println("Final result: " + sharedNumber);
}
private synchronized static void incrementSharedNumber() {
sharedNumber++;
}
}
方案2:原子类
Java提供了一些原子类(Atomic Classes),它们提供了原子性操作,即在单个操作中完成读取和写入,而不会被其他线程中断。
原子类的操作是不可分割的,也就是说,一个线程的原子操作不会被其他线程中断。这种特性使得原子类非常适合在多线程环境中保证共享变量的正确性。
import java.util.concurrent.atomic.AtomicInteger;
public class SharedResourceExample {
private static AtomicInteger sharedNumber = new AtomicInteger(0);
public static void main(String[] args) {
// 创建多个线程进行加法操作
for (int i = 0; i < 5; i++) {
new Thread(() -> {
for (int j = 0; j < 10000; j++) {
incrementSharedNumber();
}
}).start();
}
// 等待所有线程执行完毕
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 输出结果
System.out.println("Final result: " + sharedNumber);
}
private static void incrementSharedNumber() {
sharedNumber.incrementAndGet();
}
}
方案3:可重入锁
创建一个可重入锁对象 ReentrantLock(),在 incrementSharedNumber
方法使用了 ReentrantLock
,在执行临界区代码之前调用 lock.lock()
来获取锁,确保同一时刻只有一个线程能够执行 sharedNumber++
。finally
块中的 lock.unlock()
用于释放锁,确保在发生异常时也能够正确释放锁。
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class SharedResourceExample {
private static int sharedNumber = 0;
private static final Lock lock = new ReentrantLock();
public static void main(String[] args) {
// 创建多个线程进行加法操作
for (int i = 0; i < 5; i++) {
new Thread(() -> {
for (int j = 0; j < 10000; j++) {
incrementSharedNumber();
}
}).start();
}
// 等待所有线程执行完毕
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 输出结果
System.out.println("Final result: " + sharedNumber);
}
private static void incrementSharedNumber() {
lock.lock(); // 加锁
try {
sharedNumber++;
} finally {
lock.unlock(); // 释放锁
}
}
}