【多线程与高并发】5-容器
Vector和HashTable
自带锁,现基本不用
HashMap



ConcurrentHashMap
内部用了CAS,高并发,查询效率高

ConcurrentSkipListMap
高并发并且有序(代替TreeMap,因为TreeMap用了红黑树,较为复杂,因此没有ConcurrentTreeMap)
树的结构是由concurrent+CAS
跳表结构:

CopyOnWriteArrayList
写时复制容器
多线程环境下,写时效率低(加锁),读时效率高(不加锁),适合写少读多的环境。
插入元素时,拷贝原list并扩展,最后将原list引用指向新list。
BlockingQueue
offer 加,poll 取出来并remove , peek 取出来不remove(非阻塞,都会报异常但offer除外-它有返回值)
特点:put 装,take 取  (两个都为阻塞,比如取不到一直等待,使用到了Condition,调用了await,底层用到了park,进入wait状态)
Queue对线程友好的api:offer(满了也不会抛异常,根据返回值判断)、peek、poll ,
BlockingQueue在原基础上添加了put(满了阻塞)、add(满了抛出异常)、take(没有了阻塞)
- 
LinkedBlockingQueue(无界队列) 
- 
ArrayBlockingQueue(有界队列) 
 使用 ReentrantLock 和 Condition 实现一个阻塞队列
- 
DelayQueue 
 延迟队列提供了在指定时间才能获取队列元素的功能,可用作任务调度。
- 
SynchronousQueue(同步队列) 
 典型应用:线程池
 实际上它不是一个真正的队列,因为它不会为队列中元素维护存储空间。与其他队列不同的是,它维护一组线程,这些线程在等待着把元素加入或移出队列。(轻量级)可用来在线程间安全的交换单一元素。
 SynchronousQueue没有存储功能,因此put和take会一直阻塞,直到有另一个线程已经准备好参与到交付过程中。仅当有足够多的消费者,并且总是有一个消费者准备好获取交付的工作时,才适合使用同步队列。
- 
TransferQueue(LinkedTransferQueue无界阻塞队列) 
 LinkedBolckingQueue 和 SynchronousQueue 和合体
 相比较 SynchronousQueue 多了一个可以存储的队列,相比较LinkedBlockingQueue 多了直接传递元素,少了用锁来同步。性能更高,用处更大。当 put 时,如果有等待的线程,就直接将元素 “交给” 等待者, 否则直接进入队列。
 典型应用:线程池
 put和 transfer 方法的区别是,put 是立即返回的, transfer 是阻塞等待消费者拿到数据才返回。transfer方法和 SynchronousQueue的 put 方法类似。
  
eg:顾客付钱完成后,才能反馈。
- PriorityQueue
 基于优先级的无界优先级队列。优先级队列的元素按照其自然顺序进行排序,或者根据构造队列时提供的 Comparator 进行排序,具体取决于所使用的构造方法。该队列不允许使用 null 元素也不允许插入不可比较的对象(没有实现Comparable接口的对象)。
 内部实现-2叉树(堆排序)

案例
如何实现两个线程循环打印?thread1:A B C D thread2:1 2 3 4 结果:1A2B...
Locksupport park
public class T02_00_LockSupport {
    static Thread t1 = null, t2 = null;
    public static void main(String[] args) throws Exception {
        char[] aI = "1234567".toCharArray();
        char[] aC = "ABCDEFG".toCharArray();
        t1 = new Thread(() -> {
                for(char c : aI) {
                    System.out.print(c);
                    LockSupport.unpark(t2); //叫醒T2
                    LockSupport.park(); //T1阻塞
                }
        }, "t1");
        t2 = new Thread(() -> {
            for(char c : aC) {
                LockSupport.park(); //t2阻塞
                System.out.print(c);
                LockSupport.unpark(t1); //叫醒t1
            }
        }, "t2");
        t1.start();
        t2.start();
    }
}
CAS
public class T03_00_cas {
    enum ReadyToRun {T1, T2}
    static volatile ReadyToRun r = ReadyToRun.T1; //思考为什么必须volatile
    public static void main(String[] args) {
        char[] aI = "1234567".toCharArray();
        char[] aC = "ABCDEFG".toCharArray();
        new Thread(() -> {
            for (char c : aI) {
                while (r != ReadyToRun.T1) {}
                System.out.print(c);
                r = ReadyToRun.T2;
            }
        }, "t1").start();
        new Thread(() -> {
            for (char c : aC) {
                while (r != ReadyToRun.T2) {}
                System.out.print(c);
                r = ReadyToRun.T1;
            }
        }, "t2").start();
    }
}
ArrayBlockingQueue
public class T04_00_BlockingQueue {
    static BlockingQueue<String> q1 = new ArrayBlockingQueue(1);
    static BlockingQueue<String> q2 = new ArrayBlockingQueue(1);
    public static void main(String[] args) throws Exception {
        char[] aI = "1234567".toCharArray();
        char[] aC = "ABCDEFG".toCharArray();
        new Thread(() -> {
            for(char c : aI) {
                System.out.print(c);
                try {
                    q1.put("ok");
                    q2.take();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, "t1").start();
        new Thread(() -> {
            for(char c : aC) {
                try {
                    q1.take();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.print(c);
                try {
                    q2.put("ok");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, "t2").start();
    }
}
AtomicInteger
public class T05_00_AtomicInteger {
    static AtomicInteger threadNo = new AtomicInteger(1);
    public static void main(String[] args) {
        char[] aI = "1234567".toCharArray();
        char[] aC = "ABCDEFG".toCharArray();
        new Thread(() -> {
            for (char c : aI) {
                while (threadNo.get() != 1) {}
                System.out.print(c);
                threadNo.set(2);
            }
        }, "t1").start();
        new Thread(() -> {
            for (char c : aC) {
                while (threadNo.get() != 2) {}
                System.out.print(c);
                threadNo.set(1);
            }
        }, "t2").start();
    }
}
sync_wait_notify
public class T07_00_sync_wait_notify {
    private static volatile boolean t2Started = false;
    //private static CountDownLatch latch = new C(1);
    public static void main(String[] args) {
        final Object o = new Object();
        char[] aI = "1234567".toCharArray();
        char[] aC = "ABCDEFG".toCharArray();
        new Thread(()->{
            //latch.await();
            synchronized (o) {
                while(!t2Started) {
                    try {
                        o.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                for(char c : aI) {
                    System.out.print(c);
                    try {
                        o.notify();
                        o.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                o.notify();
            }
        }, "t1").start();
        new Thread(()->{
            synchronized (o) {
                for(char c : aC) {
                    System.out.print(c);
                    //latch.countDown()
                    t2Started = true;
                    try {
                        o.notify();
                        o.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                o.notify();
            }
        }, "t2").start();
    }
}
lock_condition
public static void main(String[] args) {
        char[] aI = "1234567".toCharArray();
        char[] aC = "ABCDEFG".toCharArray();
        Lock lock = new ReentrantLock();
        Condition condition = lock.newCondition();
        new Thread(()->{
            try {
                lock.lock();
                for(char c : aI) {
                    System.out.print(c);
                    condition.signal();
                    condition.await();
                }
                condition.signal();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        }, "t1").start();
        new Thread(()->{
            try {
                lock.lock();
                for(char c : aC) {
                    System.out.print(c);
                    condition.signal();
                    condition.await();
                }
                condition.signal();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        }, "t2").start();
    }
PipedStream
public static void main(String[] args) throws Exception {
        char[] aI = "1234567".toCharArray();
        char[] aC = "ABCDEFG".toCharArray();
        PipedInputStream input1 = new PipedInputStream();
        PipedInputStream input2 = new PipedInputStream();
        PipedOutputStream output1 = new PipedOutputStream();
        PipedOutputStream output2 = new PipedOutputStream();
        input1.connect(output2);
        input2.connect(output1);
        String msg = "Your Turn";
        new Thread(() -> {
            byte[] buffer = new byte[9];
            try {
                for(char c : aI) {
                    input1.read(buffer);
                    if(new String(buffer).equals(msg)) {
                        System.out.print(c);
                    }
                    output1.write(msg.getBytes());
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }, "t1").start();
        new Thread(() -> {
            byte[] buffer = new byte[9];
            try {
                for(char c : aC) {
                    System.out.print(c);
                    output2.write(msg.getBytes());
                    input2.read(buffer);
                    if(new String(buffer).equals(msg)) {
                        continue;
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }, "t2").start();
    }
Exchanger
public class T12_00_Exchanger_Not_Work {
    private static Exchanger<String> exchanger = new Exchanger<>();
    public static void main(String[] args) {
        char[] aI = "1234567".toCharArray();
        char[] aC = "ABCDEFG".toCharArray();
        new Thread(()->{
            for(int i=0; i<aI.length; i++) {
                System.out.print(aI[i]);
                try {
                    exchanger.exchange("T1");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();
        new Thread(()->{
            for(int i=0; i<aC.length; i++) {
                try {
                    exchanger.exchange("T2");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.print(aC[i]);
            }
        }).start();
    }
}
TransferQueue
public static void main(String[] args) {
        char[] aI = "1234567".toCharArray();
        char[] aC = "ABCDEFG".toCharArray();
        TransferQueue<Character> queue = new LinkedTransferQueue<Character>();
        new Thread(()->{
            try {
                for (char c : aI) {
                    System.out.print(queue.take());
                    queue.transfer(c);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }, "t1").start();
        new Thread(()->{
            try {
                for (char c : aC) {
                    queue.transfer(c);
                    System.out.print(queue.take());
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }, "t2").start();
    }
 
                    
                
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号