线程安全类--Collections.synchronizedList()
来源:互联网 发布:c语言保留三位小数 编辑:程序博客网 时间:2024/05/16 05:54
当一个类已经很好的同步以保护它的数据时,这个类就称为“线程安全的”。
即使是线程安全类,也应该特别小心,因为操作的线程是间仍然不一定安全。
举个形象的例子,比如一个集合是线程安全的,有两个线程在操作同一个集合对象,当第一个线程查询集合非空后,删除集合中所有元素的时候。第二个线程也来执行与第一个线程相同的操作,也许在第一个线程查询后,第二个线程也查询出集合非空,但是当第一个执行清除后,第二个再执行删除显然是不对的,因为此时集合已经为空了。
看个代码:
public class NameList {
private List nameList = Collections.synchronizedList(new LinkedList());
public void add(String name) {
nameList.add(name);
}
public String removeFirst() {
if (nameList.size() > 0) {
return (String) nameList.remove(0);
} else {
return null;
}
}
}
private List nameList = Collections.synchronizedList(new LinkedList());
public void add(String name) {
nameList.add(name);
}
public String removeFirst() {
if (nameList.size() > 0) {
return (String) nameList.remove(0);
} else {
return null;
}
}
}
public class Test {
public static void main(String[] args) {
final NameList nl = new NameList();
nl.add("aaa");
class NameDropper extends Thread{
public void run(){
String name = nl.removeFirst();
System.out.println(name);
}
}
Thread t1 = new NameDropper();
Thread t2 = new NameDropper();
t1.start();
t2.start();
}
}
public static void main(String[] args) {
final NameList nl = new NameList();
nl.add("aaa");
class NameDropper extends Thread{
public void run(){
String name = nl.removeFirst();
System.out.println(name);
}
}
Thread t1 = new NameDropper();
Thread t2 = new NameDropper();
t1.start();
t2.start();
}
}
运行结果:
虽然集合对象
private List nameList = Collections.synchronizedList(new LinkedList());
是同步的,但是程序还不是线程安全的。
是同步的,但是程序还不是线程安全的。
出现这种事件的原因是,上例中一个线程操作列表过程中无法阻止另外一个线程对列表的其他操作。
解决上面问题的办法是,在操作集合对象的NameList上面做一个同步。改写后的代码如下:
public class NameList {
private List nameList = Collections.synchronizedList(new LinkedList());
public synchronized void add(String name) {
nameList.add(name);
}
public synchronized String removeFirst() {
if (nameList.size() > 0) {
return (String) nameList.remove(0);
} else {
return null;
}
}
}
private List nameList = Collections.synchronizedList(new LinkedList());
public synchronized void add(String name) {
nameList.add(name);
}
public synchronized String removeFirst() {
if (nameList.size() > 0) {
return (String) nameList.remove(0);
} else {
return null;
}
}
}
这样,当一个线程访问其中一个同步方法时,其他线程只有等待。
0 0
- 线程安全类--Collections.synchronizedList()
- 线程安全Collections.synchronizedList
- 线程安全Collections.synchronizedList
- 线程安全Collections.synchronizedList
- 线程安全Collections.synchronizedList
- 线程安全Collections.synchronizedList
- 线程安全之Collections.synchronizedList
- 线程安全之Collections.synchronizedList
- 线程安全的Collections.synchronizedList
- Java基础之集合框架--Collections.synchronizedList() 线程安全的List
- Collections.synchronizedList
- Collections.synchronizedList
- Collections.synchronizedList
- Collections.synchronizedList 初次使用
- Collections.synchronizedList 工厂方法
- Collections分析之SynchronizedList
- Collections.synchronizedList(list)
- Collections.synchronizedList()方法
- Node.js 处理JSON
- Unix环境高级编程读书笔记(线程)
- LockSupport简单讲解及实例
- 安卓与单片机进行usb hid通信
- spring控制数据库读写分离(多数据源动态切换)
- 线程安全类--Collections.synchronizedList()
- centos 7上部署dubbo-admin-2.4.1 在jdk8运行出现问题
- jquery获取url传递参数
- 下沉的船
- Linux 下三种方式设置环境变量
- Node.js 使用Buffer模块缓存数据
- SQLiteDatabase中的query方法,里面有个用占位符代替的参数,不错
- 5分钟了解MySQL5.7对in用法有什么黑科技
- adb dumpsys