1、关键字 volatile
使用场景: 针对与多线程公用的数据 用volatile关键字修饰 但其不保证原子性(同步)。volatile关键字不具备synchronized关键
字的原子性(同步)
实例讲解:在一个类,启动一个线程, 在线程里面判断如果全局公用的数据发生改变的时候,立即停止线程。
2、关键字 wait notfiy 方法,wait释放锁,notfiy不释放锁
注意事项:当使用wait 和 notify 的时候 , 一定要配合着synchronized关键字去使用
解决不释放锁的方式:
使用import java.util.concurrent.CountDownLatch;的CountDownLatch类
countDownLatch.countDown(); 相当于 notfiy; countDown()会释放锁
countDownLatch.await();相当于 wait;
3、队列 Queue
BlockingQueue(有界阻塞队列):put(Object): 把Object加到BlockingQueue里,如果BlockQueue没有空间,则调用此方法的线程
被阻断,直到BlockingQueue里面有空间再继续.removeFirst();取走BlockingQueue里排在首位的对象,若
BlockingQueue为空,阻断进入等待状态直到BlockingQueue有新的数据被加入.
4、关键字ThreadLocal
使用场景:ThreadLocal修饰的集合或者属性 只在当前线程有效
5、单例模式
1 public class DubbleSingleton { 2 3 4 private static DubbleSingleton ds; 5 6 public static DubbleSingleton getDs(){ 7 if(ds == null){ 8 try { 9 //模拟初始化对象的准备时间... 10 Thread.sleep(3000); 11 } catch (InterruptedException e) { 12 e.printStackTrace(); 13 } 14 synchronized (DubbleSingleton.class) { 15 if(ds == null){ 16 ds = new DubbleSingleton(); 17 } 18 } 19 } 20 return ds; 21 } 22 }
6、内部类处理线程安全
1 public class Singletion { 2 3 private static class InnerSingletion { 4 private static Singletion single = new Singletion(); 5 } 6 7 public static Singletion getInstance(){ 8 return InnerSingletion.single; 9 } 10 11 }
7、Vector 和HashTable 集合 , 多线程使用Vector或者HashTable的示例(简单线程同步问题)
使用场景: 初始化火车票池并添加火车票:避免线程同步可采用Vector替代ArrayList HashTable替代HashMap
8、ConcurrentHashMap 集合
使用场景: 存在相同key 第二次Key保存就会失败 但不会有异常
9、 LinkedBlockingQueue队列
使用场景: 阻塞无界队列 peekFirst获取到第一个元素 但不移除 pollLast获取到最后一个元素 会移除
注意:初始化没有长度 表示无界 有长度,表示有界
10、 PriorityBlockingQueue队列
使用场景: 根据一定规则,自动排序
注意事项:机制:队列使用.take()方法时,自动重新排序 如果直接保存,然后for循环打印,不会自动排序
11、 ConcurrentLinkedQueue 高性能无阻塞无界队列
使用场景:高并发 高性能数据集合
使用方式 :
8、ConcurrentHashMap 集合
使用场景: 存在相同key 第二次Key保存就会失败 但不会有异常
9、 LinkedBlockingQueue队列
使用场景: 阻塞无界队列 peekFirst获取到第一个元素 但不移除 pollLast获取到最后一个元素 会移除
注意:初始化没有长度 表示无界 有长度,表示有界
10、 PriorityBlockingQueue队列
使用场景: 根据一定规则,自动排序
注意事项:机制:队列使用.take()方法时,自动重新排序 如果直接保存,然后for循环打印,不会自动排序
11、 ConcurrentLinkedQueue 高性能无阻塞无界队列
使用场景:高并发 高性能数据集合
使用方式 :
增加元素:add(object) 或 offer(object);
移除元素:poll() 从头部取出元素,并从队列里删除
获取元素:peek() 从头部取出元素
12、ArrayBlockingQueue 有界队列 初始化必须传长度
使用方式:array.offer("a", 2, TimeUnit.SECONDS); //2S 内加入a 如果加入成功返回true 否则 返回false
注意事项: offer put add都是阻塞的
13、LinkedBlockingQueue 阻塞队列 初始化可以不传长度 不传变成无界队列
特别使用方式:
a.drainTo(list,N) 表示:从队列里面抽出N个元素放在list集合里面
a:表示LinkedBlockingQueue 队列 list为新建的list集合 n:元素个数
14、SynchronousQueue 没有大小的队列。
使用场景:在特定的日期,不需要队列的时候,要提高性能时,就可以使用SynchronousQueue 。相当于在队列中过一下
实例://SynchronousQueue没有大小 相当于只是在其中通过一下
1 final SynchronousQueue<String> q = new SynchronousQueue<String>(); 2 Thread t1 = new Thread(new Runnable() { 3 @Override 4 public void run() { 5 try { 6 System.out.println(q.take()); 7 } catch (InterruptedException e) { 8 e.printStackTrace(); 9 } 10 } 11 }); 12 t1.start(); 13 Thread t2 = new Thread(new Runnable() { 14 15 @Override 16 public void run() { 17 q.add("asdasd"); 18 } 19 }); 20 t2.start(); 21 } 22 23 24