在网上看到的一篇文章,如下:
vector线程安全 ArrayList非线程安全,但却解约系统性能
比如一个 ArrayList 类,在添加一个元素的时候,它可能会有两步来完成:
1. 在 Items[Size] 的位置存放此元素;
2. 增大 Size 的值。
在单线程运行的情况下,如果 Size = 0,添加一个元素后,此元素在位置 0,而且 Size=1;
而如果是在多线程情况下,比如有两个线程,线程 A 先将元素存放在位置 0。但是此时 CPU 调度线程A暂停,线程 B 得到运行的机会。线程B也向此 ArrayList 添加元素,因为此时 Size 仍然等于 0 (注意哦,我们假设的是添加一个元素是要两个步骤哦,而线程A仅仅完成了步骤1),所以线程B也将元素存放在位置0。然后线程A和线程B都继续运行,都增加 Size 的值。
那好,现在我们来看看 ArrayList 的情况,元素实际上只有一个,存放在位置 0,而 Size 却等于 2。这就是“线程不安全”了。
然后我写了测试的例子。
发现都没有抛出异常啊。是不是我写的例子有问题?谁给我个演示ArrayList线程不安全的列子呢?谢谢了。
- Java code
import java.util.Vector;//实现Runnable接口的线程public class HelloThread implements Runnable { String name; Vector v; HelloThread(String name,Vector v) { this.name = name; this.v = v; } public void run() { /* * int sleeptime=(int)(Math.random()*3000); ///A try{ //B * Thread.sleep(sleeptime); ///C }catch(InterruptedException e){} ///D */ System.out.println(name+"start"); v.add(name+".add"); } public static void main(String args[]) throws InterruptedException { Vector v = new Vector(); HelloThread hello1 = new HelloThread("hello1",v); HelloThread hello2 = new HelloThread("hello2",v); HelloThread hello3 = new HelloThread("hello3",v); Thread h1 = new Thread(hello1); Thread h2 = new Thread(hello2); Thread h3 = new Thread(hello3); h1.start(); h2.start(); h3.start(); try { Thread.sleep(1000); } catch (InterruptedException e) { System.out.println(e.getMessage()); } for(int i=0;i<v.size();i++){ System.out.println(v.get(i)); } }}
- Java code
import java.util.ArrayList;import java.util.List;import java.util.Vector;//实现Runnable接口的线程public class HelloThread implements Runnable { String name; List v; HelloThread(String name,List v) { this.name = name; this.v = v; } public void run() { System.out.println(name+"start"); v.add(name+".add"); } public static void main(String args[]) throws InterruptedException { List v = new ArrayList(); HelloThread hello1 = new HelloThread("hello1",v); HelloThread hello2 = new HelloThread("hello2",v); HelloThread hello3 = new HelloThread("hello3",v); Thread h1 = new Thread(hello1); Thread h2 = new Thread(hello2); Thread h3 = new Thread(hello3); h1.start(); h2.start(); h3.start(); try { Thread.sleep(1000); } catch (InterruptedException e) { System.out.println(e.getMessage()); } System.out.println("v.size:"+v.size()); for(int i=0;i<v.size();i++){ System.out.println(v.get(i)); } }}
------解决方案--------------------------------------------------------
对你的程序稍作改动
- Java code
package com.xuz.csdn.worldcup.day7;import java.util.ArrayList;import java.util.List;//实现Runnable接口的线程public class HelloThread implements Runnable { String name; List<String> v; HelloThread(String name, List<String> v) { this.name = name; this.v = v; } public void run() { System.out.println(name + "start"); while(true){ v.add(name + ".add"); System.out.println(name + " list size is " + v.size()); try { Thread.sleep(1000); } catch (InterruptedException e) { System.out.println(e.getMessage()); } } } public static void main(String args[]) throws InterruptedException { List<String> v = new ArrayList<String>(); HelloThread hello1 = new HelloThread("hello1", v); HelloThread hello2 = new HelloThread("hello2", v); HelloThread hello3 = new HelloThread("hello3", v); Thread h1 = new Thread(hello1); Thread h2 = new Thread(hello2); Thread h3 = new Thread(hello3); h1.start(); h2.start(); h3.start();// try {// Thread.sleep(1000);// } catch (InterruptedException e) {// System.out.println(e.getMessage());// }// System.out.println("v.size:" + v.size());// for (int i = 0; i < v.size(); i++) {// System.out.println(v.get(i));// } }}