Java锁Synchronized的使用
在多线程编程中,为了保证共享资源的安全访问,我们需要使用锁来控制线程的访问顺序和互斥访问。Java中的Synchronized关键字是一种加锁机制,可以用于方法或代码块,用于实现线程的同步。
什么是Synchronized关键字?
Synchronized是Java中用于实现线程同步的关键字,它可以用于修饰方法和代码块。当一个方法或代码块被Synchronized修饰时,它就变成了一个同步方法或同步代码块。在同步方法或代码块中,一次只能有一个线程访问该方法或代码块,其他线程必须等待。
Synchronized的基本用法
同步方法
首先,我们来看一下Synchronized关键字在方法上的使用。当我们将一个方法声明为Synchronized时,该方法成为一个同步方法。
public class SynchronizedExample {
private int count = 0;
public synchronized void increment() {
count++;
}
}
上面的代码中,我们声明了一个名为increment
的同步方法,该方法的作用是将count
的值增加1。由于该方法被Synchronized修饰,因此在同一时间只能有一个线程访问该方法。
同步代码块
除了在方法上使用Synchronized关键字,我们还可以在代码块中使用它来实现同步。下面是一个示例:
public class SynchronizedExample {
private int count = 0;
private Object lock = new Object();
public void increment() {
synchronized (lock) {
count++;
}
}
}
在上面的代码中,我们使用了一个对象lock
来实现同步。在increment
方法中,我们使用了一个Synchronized代码块,该代码块的锁对象是lock
。这样,同一时间只能有一个线程访问该代码块。
Synchronized的使用场景
Synchronized关键字的使用场景通常是在多线程访问共享资源的情况下。下面是几个常见的使用场景:
1. 多线程访问共享变量
当多个线程同时访问一个共享变量时,我们需要使用Synchronized来保证对该变量的互斥访问,以避免数据不一致的问题。
public class SynchronizedExample {
private int count = 0;
public synchronized void increment() {
count++;
}
public synchronized int getCount() {
return count;
}
}
在上面的代码中,increment
方法和getCount
方法都被声明为同步方法。这样,当多个线程同时调用这两个方法时,对count
变量的访问就是互斥的。
2. 保护共享资源
在多线程环境中,有时候我们需要保护一段关键代码,使得只有一个线程能够执行它。这时候,我们可以使用Synchronized代码块来实现。
public class SynchronizedExample {
private int count = 0;
private Object lock = new Object();
public void increment() {
synchronized (lock) {
count++;
}
}
public void decrement() {
synchronized (lock) {
count--;
}
}
}
在上面的代码中,increment
方法和decrement
方法都使用了Synchronized代码块,并且使用了同一个锁对象lock
。这样,同一时间只能有一个线程执行这两个方法。
3. 线程安全的集合类
在Java中,有一些集合类不是线程安全的,比如ArrayList、HashMap等。如果我们需要在多线程环境下使用这些集合类,就需要使用Synchronized来保证它们的线程安全性。
List<String> list = Collections.synchronizedList(new ArrayList<>());
Map<String, String> map = Collections.synchronizedMap(new HashMap<>());
在上面的代码中,我们通过Collections
类的静态方法创建了一个线程安全的List和Map。这样,我们就可以在多线程环境中安全地使用它们。