- 首先给出结论,ArrayList,LinkedList,HashMap,StringBuilder是不安全的。vector,HashTable,StringBuffer是线程安全的。下面用代码来看看。
- ArrayList测试
package testThread;
import java.util.ArrayList;
import java.util.List;
class Ticket implements Runnable {
private static int t=0;
List<Integer> data = new ArrayList<>();
boolean flag=true;
public void run() {
while (flag) {
if (t<100) {
data.add(t);
t++;
//System.out.println(t);
}else {
flag=false;
System.out.println("数据宽度"+data.size());
for (int i = 0; i < data.size(); i++) {
System.out.println(data.get(i));
}
}
}
}
}
public class thread1 {
public static void main(String[] args)
{
Ticket t=new Ticket();
Thread t1=new Thread(t);
Thread t2=new Thread(t);
Thread t3=new Thread(t);
t1.start();
t2.start();
t3.start();
}
}
ArrayList测试结果
2.LinkedList
package te;
import java.util.LinkedList;
import java.util.List;
class Ticket implements Runnable {
private static int t=0;
List<Integer> data = new LinkedList<Integer>();
boolean flag=true;
public void run() {
while (flag) {
if (t<100) {
data.add(t);
t++;
//System.out.println(t);
}else {
flag=false;
System.out.println("数据宽度"+data.size());
for (int i = 0; i < data.size(); i++) {
System.out.println(data.get(i));
}
}
}
}
}
public class Thread7 {
public static void main(String[] args)
{
Ticket t=new Ticket();
Thread t1=new Thread(t);
Thread t2=new Thread(t);
Thread t3=new Thread(t);
t1.start();
t2.start();
t3.start();
}
}
LinkedList结果
3.HashMap
package te;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
class Ticket implements Runnable {
private static int t=0;
Map data = new HashMap<Integer,Integer>();
boolean flag=true;
public void run() {
while (flag) {
if (t<100) {
data.put(t,t);
t++;
//System.out.println(t);
}else {
flag=false;
Collection da=data.values();
Iterator<Integer> it=da.iterator();
while (it.hasNext()) {
Integer integer = (Integer) it.next();
System.err.println(integer);
}
}
}
}
}
public class Thread7 {
public static void main(String[] args)
{
Ticket t=new Ticket();
Thread t1=new Thread(t);
Thread t2=new Thread(t);
Thread t3=new Thread(t);
t1.start();
t2.start();
t3.start();
}
}
HashMap测试
4.vector
package te;
import java.util.Vector;
class Ticket implements Runnable {
private static int t=0;
Vector<Integer> vector=new Vector<Integer>();
boolean flag=true;
public void run() {
while (flag) {
if (t<100) {
vector.add(t);
t++;
}else {
flag=false;
for(int i=0;i<vector.size();i++)
{
System.out.println(vector.get(i));
}
}
}
}
}
public class Thread7 {
public static void main(String[] args)
{
Ticket t=new Ticket();
Thread t1=new Thread(t);
Thread t2=new Thread(t);
Thread t3=new Thread(t);
t1.start();
t2.start();
t3.start();
}
}
vector线程是安全的
5.stringbuilder和stringbuffer
package te;
class Ticket implements Runnable {
private static int t=0;
StringBuffer sb = new StringBuffer();
StringBuilder sc=new StringBuilder();
boolean flag=true;
public void run() {
while (flag) {
if (t<100) {
sb.append(t+"a ");
sc.append(t+"a ");
t++;
}else {
flag=false;
System.out.println("stringbuffer"+sb);
System.out.println("stringbuilder"+sc);
}
}
}
}
public class Thread7 {
public static void main(String[] args)
{
Ticket t=new Ticket();
Thread t1=new Thread(t);
Thread t2=new Thread(t);
Thread t3=new Thread(t);
t1.start();
t2.start();
t3.start();
}
}
结果测试 stringbuilder是不安全的
6.分析总结
凡是线程不安全的,我们可以来看源码来分析 ,这是arraylist的源码,我们很容易发现这是由于没有synchronized关键字。
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
再来看看vector,有synchronized关键字。
public synchronized boolean add(E e) {
modCount++;
ensureCapacityHelper(elementCount + 1);
elementData[elementCount++] = e;
return true;
}