适用于多线程环境下的集合类:
1、阻塞队列:ArrayBlockingQueue(数组实现队列),LinkedBlockingQueue(链表实现队列)
public class BlockingQueueTest {
public static void main(String[] args) {
final BlockingQueue queue = new ArrayBlockingQueue(3);
for(int i=0;i<2;i++){
new Thread(){
public void run(){
while(true){
try {
Thread.sleep((long)(Math.random()*1000));
System.out.println(Thread.currentThread().getName() + "准备放数据!");
queue.put(1);
System.out.println(Thread.currentThread().getName() + "已经放了数据," +
"队列目前有" + queue.size() + "个数据");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
}
new Thread(){
public void run(){
while(true){
try {
//将此处的睡眠时间分别改为100和1000,观察运行结果
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName() + "准备取数据!");
queue.take();
System.out.println(Thread.currentThread().getName() + "已经取走数据," +
"队列目前有" + queue.size() + "个数据");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
}
}
2、阻塞队列线程间通信,如下通过阻塞队列也可以实现线程间通信,你一下我一下的间隔运行,这就是利用阻塞队列的阻塞方法put和take,其实用lock的等待唤醒也照样可以实现
static class Business {
BlockingQueue<Integer> queue1 = new ArrayBlockingQueue<Integer>(1);
BlockingQueue<Integer> queue2 = new ArrayBlockingQueue<Integer>(1);
{//匿名构造方法,任何构造方法调用之前都会走匿名构造方法块
//加static的话是静态代码块,只在类加载时运行一次
Collections.synchronizedMap(null);
try {
System.out.println("xxxxxdfsdsafdsa");
queue2.put(1);//一上来queue2放满
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void sub(int i){
try {
queue1.put(1);//queue1没满放进去一个,进入下面代码,取走queue2,queue2空出
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
for(int j=1;j<=10;j++){
System.out.println("sub thread sequece of " + j + ",loop of " + i);
}
try {
queue2.take();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void main(int i){
try {
queue2.put(1);//上来时queue2已满,放不进等着queue1取数据,只要一空立马插入一个
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
for(int j=1;j<=100;j++){
System.out.println("main thread sequece of " + j + ",loop of " + i);
}
try {
queue1.take();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
其他适用于多线程的集合类都位于java.util.concurrent包下,普通的集合不适合多线程操作,如Array,HashMap等,适合多线程的集合有ConcurrentHashMap等,JDK1.5之前没有并发的集合,这时一般通过Collections集合工具类想的不同同步方法,如synchronizedMap来把普通HashMap转为线程安全的加锁的HashMap,但是效率低了,所以操作多线程时推荐使用JDK1.5之后的java.util.concurrent包下的多线程集合,其是部分加锁,而不是所有方法加锁,所以效率比1.5之前的高些,同样的还有8大数据类型的对应线程安全类型,前面都是加atomic的,位于java.util.concurrent.atomic包下,如AtomicInteger,其内部自己维护了多线程操作时的++和--,内部也就是自己加了synchronized关键字,这样就省去了自己去维护线程安全