package com.gray.test;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;
public class ThreadTest {
public static void main(String[] args) throws Exception {
// 开始时间
long start = System.currentTimeMillis();
// 模拟数据List
List list = new ArrayList();
for (int i = 0; i < 3000; i++) {
list.add(i + "");
}
ExecutorService exec = Executors.newFixedThreadPool(3);
CountDownLatch doneSignal = new CountDownLatch(3);
exec.execute(new PoiWriter(doneSignal,list,0,999));
exec.execute(new PoiWriter(doneSignal,list,1000,1999));
exec.execute(new PoiWriter(doneSignal,list,2000,2999));
doneSignal.await();
exec.shutdown();
System.out.println("执行任务消耗了 :" + (System.currentTimeMillis() - start) + "毫秒");
}
protected static class PoiWriter implements Runnable {
private CountDownLatch doneSignal;
private List list;
private int start;
private int end;
public PoiWriter(CountDownLatch doneSignal,List list, int start, int end) {
this.doneSignal = doneSignal;
this.start = start;
this.list = list;
this.end = end;
}
@Override
public void run() {
try {
for (int i = start; i <= end ;i++) {
list.set(i, Thread.currentThread().getName() +"<--------->" + list.get(i));
System.out.println(list.get(i));
}
} catch (Exception e) {
e.printStackTrace();
} finally {
doneSignal.countDown();
}
}
}
}
用synchronized包裹list操作的部分代码
list本身是线程不安全的,你可以用Collections.synchronizedList包装下
https://www.cnblogs.com/yaowen/p/5983136.html
要想保证线程安全我觉得有三种方式,最见到的是使用List list = new Vector(); 因为它本身就是线程安全的,只不过效率上要比ArrayList差点
第二种就是使用synchronized,上面已有回答,但是我觉得还是Vector简单点。
第三种是使用读写锁,ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();
rwLock.writeLock().lock();
rwLock.writeLock().unlock();
rwLock.readLock().lock();
rwLock.readLock().unlock();
需要注意的是每次用完锁都记得释放,否则会发生死锁。
java.util.concurrent.CopyOnWriteArrayList<E>
使用List list = new Vector();
三个线程都是对同一个list取值,但是并没有修改这个list,为什么会不安全,是我没有 看出哪里不安全?你这里都没有共享数据会被修改啊!
没问题,数据都已经分开处理了