Java中的Collections synchronizedList()方法及其示例
Java是一种面向对象的编程语言,其集合框架提供了许多数据结构和算法实现,方便程序员快速开发和实现功能。而在多线程环境下,Java的Collection框架并不是线程安全的,这就需要程序员自行实现线程安全。
Java提供了许多同步集合类,其中就包括Collections
类中的SynchronizedList()
方法。
Collections类
java.util.Collections
是Java集合框架中的一个工具类,提供了许多静态方法,方便程序员使用和管理集合类。
其中,Collections.synchronizedList()
方法是用来将普通的List转化为线程安全的List,方法的签名如下所示:
public static <T> List<T> synchronizedList(List<T> list)
参数list
是要被同步的List,返回一个线程安全的List,具有线程安全的迭代器以及add和remove操作。
注意:SynchronizedList
方法并不是完全的线程安全,它只是在每个方法内部加入了锁,实现了同步。
示例代码:
import java.util.*;
public class SynchronizedListExample {
public static void main(String args[]) {
// 初始化一个List集合
List<String> list = new ArrayList<String>();
// new一个线程A,向list中添加元素
Thread threadA = new Thread(new Runnable() {
public void run() {
for(int i = 0; i < 5; i++) {
list.add("A" + i);
System.out.println(Thread.currentThread().getName() + " 添加了元素 " + "A" + i);
try{
Thread.sleep(500);
} catch (InterruptedException ex) {}
}
}
});
// new一个线程B,向list中添加元素
Thread threadB = new Thread(new Runnable() {
public void run() {
for(int i = 0; i < 5; i++) {
list.add("B" + i);
System.out.println(Thread.currentThread().getName() + " 添加了元素 " + "B" + i);
try{
Thread.sleep(500);
} catch (InterruptedException ex) {}
}
}
});
// 启动线程A和线程B
threadA.start();
threadB.start();
try {
// 等待线程A和线程B执行完
threadA.join();
threadB.join();
} catch (InterruptedException ex) {}
// 输出list的元素个数
System.out.println("List的元素个数为: " + list.size());
}
}
输出结果:
Thread-0 添加了元素 A0
Thread-0 添加了元素 A1
Thread-1 添加了元素 B0
Thread-0 添加了元素 A2
Thread-1 添加了元素 B1
Thread-0 添加了元素 A3
Thread-1 添加了元素 B2
Thread-0 添加了元素 A4
Thread-1 添加了元素 B3
Thread-1 添加了元素 B4
List的元素个数为: 10
由于List不是线程安全的,所以在多线程环境下,向List中添加元素可能会导致线程安全问题。以上面的示例代码为例,我们会发现线程A和线程B都往List中添加了元素,但是List的元素个数却只有10个。这是因为在多线程环境下,对于非线程安全的类,多个线程同时访问可能会产生竞态条件,导致执行结果与期望不符。
所以,我们需要对List进行同步处理,避免出现线程安全问题。
使用SynchronizedList方法进行同步
Collections.synchronizedList()
方法可以很方便的将普通的List转化为线程安全的List,其实现方式就是在每个方法内部加入了锁,确保同一时间只有一个线程在操作集合。
示例代码:
import java.util.*;
public class SynchronizedListExample {
public static void main(String args[]) {
// 初始化一个List集合
List<String> list = new ArrayList<String>();
// 将list转化为线程安全的List
List<String> synchronizedList = Collections.synchronizedList(list);
// new一个线程A,向synchronizedList中添加元素
Thread threadA = new Thread(new Runnable() {
public void run() {
for(int i = 0; i < 5; i++) {
synchronizedList.add("A" + i);
System.out.println(Thread.currentThread().getName() + " 添加了元素 " + "A" + i);
try{
Thread.sleep(500);
} catch (InterruptedException ex) {}
}
}
});
// new一个线程B,向synchronizedList中添加元素
Thread threadB = new Thread(new Runnable() {
public void run() {
for(int i = 0; i < 5; i++) {
synchronizedList.add("B" + i);
System.out.println(Thread.currentThread().getName() + " 添加了元素 " + "B" + i);
try{
Thread.sleep(500);
} catch (InterruptedException ex) {}
}
}
});
// 启动线程A和线程B
threadA.start();
threadB.start();
try {
// 等待线程A和线程B执行完
threadA.join();
threadB.join();
} catch (InterruptedException ex) {}
// 输出synchronizedList的元素个数
System.out.println("SynchronizedList的元素个数为: " + synchronizedList.size());
}
}
输出结果:
Thread-0 添加了元素 A0
Thread-1 添加了元素 B0
Thread-0 添加了元素 A1
Thread-1 添加了元素 B1
Thread-0 添加了元素 A2
Thread-1 添加了元素 B2
Thread-1 添加了元素 B3
Thread-0 添加了元素 A3
Thread-1 添加了元素 B4
Thread-0 添加了元素 A4
SynchronizedList的元素个数为: 10
可以发现,通过使用Collections.synchronizedList()
方法将List转化为线程安全的List后,两个线程都能够向集合中添加元素。
总结
在多线程环境下,使用线程安全的数据结构和算法可以避免竞态条件、数据冲突等问题,提高程序的性能和并发能力。在Java中,通过java.util.Collections
提供的同步方法,可以方便地将普通的集合转化为线程安全的集合。Collections.synchronizedList()
方法就是其中之一,可以将普通的List转化为线程安全的List。
在实际开发中,需要根据具体的业务需求和场景选择合适的集合类型、同步方法以及线程安全策略,保证多线程程序的正确性和稳定性。