在Java中,synchronized关键字、ReentrantLock和volatile关键字这三个是编程中常用于实现线程同步的机制,下面结合代码详细说明一下这三个关键字的用法。
1. synchronized关键字:
synchronized关键字是Java语言提供的内置锁机制
,用于实现线程之间的同步。它可以修饰方法或代码块
,确保同一时刻只有一个线程
可以访问被synchronized修饰的代码块或方法。示例
下面使用共同操作一个共享变量count演示一下synchronized的用法,代码如下:
public class SynchronizedExample {
private int count = 0;
public synchronized void increment() {
count++;
}
public synchronized void decrement() {
count--;
}
public static void main(String[] args) {
SynchronizedExample example = new SynchronizedExample();
Thread thread1 = new Thread(() -> {
for (int i = 0; i < 1000; i++) {
example.increment();
}
});
Thread thread2 = new Thread(() -> {
for (int i = 0; i < 1000; i++) {
example.decrement();
}
});
thread1.start();
thread2.start();
try {
thread1.join();
thread2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Count: " + example.count); //Count: 0
}
}
2. ReentrantLock:
ReentrantLock是java.util.concurrent
包提供的锁机制,相比synchronized关键字更加灵活,可以实现公平锁、可中断锁
等特性。使用ReentrantLock需要手动加锁和解锁
。
代码如下:
import java.util.concurrent.locks.ReentrantLock;
public class ReentrantLockExample {
private int count = 0;
private ReentrantLock lock = new ReentrantLock();
public void decrement() {
lock.lock();
try {
count++;
} finally {
lock.unlock();
}
}
public void increment() {
lock.lock();
try {
count++;
} finally {
lock.unlock();
}
}
public static void main(String[] args) {
ReentrantLockExample example = new ReentrantLockExample();
Thread thread1 = new Thread(() -> {
for (int i = 0; i < 1000; i++) {
example.increment();
}
});
Thread thread2 = new Thread(() -> {
for (int i = 0; i < 1000; i++) {
example.decrement();
}
});
thread1.start();
thread2.start();
try {
thread1.join();
thread2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Count: " + example.count); //Count: 0
}
}
3. volatile关键字:
volatile关键字用于保证变量的可见性
,即当一个线程修改了volatile变量的值,其他线程可以立即看到最新的值
。但它并不具备原子性,不能保证复合操作的原子性。
代码如下:
public class VolatileExample {
private volatile boolean flag = false;
public void toggleFlag() {
flag = !flag;
}
public static void main(String[] args) {
VolatileExample example = new VolatileExample();
Thread thread1 = new Thread(() -> {
for (int i = 0; i < 1000; i++) {
example.toggleFlag();
}
});
Thread thread2 = new Thread(() -> {
for (int i = 0; i < 1000; i++) {
example.toggleFlag();
}
});
thread1.start();
thread2.start();
try {
thread1.join();
thread2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Flag: " + example.flag);
}
}