线程同步和锁机制
线程同步是指多个线程对共用的资源的访问是有次序的,同一时间只允许一个线程对共享资源进行访问。锁机制是同步其他线程对共享资源的访问。
synchronized的基本概念
synchronized是Java中最基本的锁定机制,通过控制对象的锁状态来实现多线程的同步。它的语法格式包括两种:
- 修饰方法,形式为:
synchronized void method(){}
- 修饰代码块,形式为:
synchronized(lock){
// synchronized block statements
}
其中,lock
是锁定的对象,synchronized
保证锁定的代码同一时刻只有一个线程执行。
Lock的基本概念
Lock是Java提供的一种更灵活、更强大的锁机制,它比synchronized多了很多高级特性,主要有以下优点:
- 可中断的锁获取
- 可限时的锁获取
- 多个条件变量
在使用Lock时,需要手动获取锁和释放锁,即在try-finally
语句块中获取锁并在finally语句块中释放锁。
下面是Lock的基本使用示例:
Lock lock = new ReentrantLock();
lock.lock();
try {
// protected code
}
finally {
lock.unlock();
}
synchronized和Lock的区别
- synchronized是Java内置的锁机制,而Lock是Java API提供的锁机制。
- synchronized在锁的使用和释放上比较简单,而Lock必须手动获取和释放。
- Lock支持更多特性,比如多个条件变量。
在多线程并发的场景中,如果只是简单的同步控制,使用synchronized就足够了。如果需要更复杂的锁机制,比如可中断锁、可限时锁、多个条件变量等,Lock会更加灵活。
synchronized和Lock的应用场景
synchronized适用于简单的并发场景,比如对一个共享变量的读写操作,或者在需要同步控制的方法上使用。synchronized还可以适用于一些比较简单的等待策略。
而Lock适用于使用更复杂锁机制场景,比如可中断锁、可限时锁、多个条件变量等。
代码示例
下面的代码演示了利用synchronized实现对共享变量的同步控制:
class Counter {
private int count = 0;
public synchronized void increment() {
count++;
}
public synchronized int getCount() {
return count;
}
}
class CounterThread extends Thread {
private Counter counter;
public CounterThread(Counter counter) {
this.counter = counter;
}
public void run() {
for (int i = 0; i < 1000; i++) {
counter.increment();
}
}
}
public class Main {
public static void main(String[] args) throws InterruptedException {
Counter counter = new Counter();
Thread thread1 = new CounterThread(counter);
Thread thread2 = new CounterThread(counter);
thread1.start();
thread2.start();
thread1.join();
thread2.join();
System.out.println(counter.getCount());
}
}
下面的代码演示了利用Lock实现对共享变量的同步控制:
class Counter {
private int count = 0;
private Lock lock = new ReentrantLock();
public void increment() {
lock.lock();
try {
count++;
}
finally {
lock.unlock();
}
}
public int getCount() {
lock.lock();
try {
return count;
}
finally {
lock.unlock();
}
}
}
class CounterThread extends Thread {
private Counter counter;
public CounterThread(Counter counter) {
this.counter = counter;
}
public void run() {
for (int i = 0; i < 1000; i++) {
counter.increment();
}
}
}
public class Main {
public static void main(String[] args) throws InterruptedException {
Counter counter = new Counter();
Thread thread1 = new CounterThread(counter);
Thread thread2 = new CounterThread(counter);
thread1.start();
thread2.start();
thread1.join();
thread2.join();
System.out.println(counter.getCount());
}
}
文章评论