一:常见的java并发类
1:AtomicBoolean
public class AtomaticTest implements Runnable {
private String name;
private static AtomicBoolean exists = new AtomicBoolean(false);
public AtomaticTest(String name) {
this.name = name;
}
public static void main(String[] args) {
AtomaticTest atomatic1 = new AtomaticTest("person1");
AtomaticTest atomatic2 = new AtomaticTest("person2");
new Thread(atomatic1).start();
new Thread(atomatic2).start();
}
@Override
public void run() {
if(exists.compareAndSet(false, true)) {
System.out.println(name + ":enter");
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(name + ":leave");
exists.set(false);
}else{
System.out.println(name +":give up");
}
}
}
输出:
person1:enter
person2:give up
person1:leave
2:AtomicInteger
private static AtomicInteger count = new AtomicInteger(0);
public static void increment() {
count.getAndIncrement();
}
3:AtomicLong
private static AtomicLong counter = new AtomicLong(0);
public static long increment() {
return counter.incrementAndGet();
}
4:引用对象的原子操作AtomicReference
4:CopyOnWriteArrayList
CopyOnWriteArrayList<Integer> list =new CopyOnWriteArrayList<Integer>();
//添加元素
list.add(1);
list.add(2);
list.set(0, 2);//在位置0处设置2
list.remove(2);//可以删除下标和元素
5:CopyOnWriteArraySet
CopyOnWriteArraySet set=new CopyOnWriteArraySet();
//添加元素
set.add("one");
set.add("two");
//刪除元素
set.remove("one");
6:ConcurrentMap
ConcurrentMap<String, Long> wordCounts = new ConcurrentHashMap<>();
System.out.println(wordCounts.putIfAbsent("111", 111L));
System.out.println(wordCounts.putIfAbsent("111", 222L));
System.out.println(wordCounts.get("111"));
//System.out.println(wordCounts.put("111", 333l));
输出:
null
111
111
7:ConcurrentLinkedQueue
/*
* add 和offer() :都是加入元素的方法 ;
* poll() 和peek() :都是取头元素节点,区别在于前者会删除元素,后者不会。
*/
ConcurrentLinkedQueue q = new ConcurrentLinkedQueue();
q.offer("张三");
q.offer("李四");
q.offer("王五");
q.offer("赵六");
// 从头获取元素,删除该元素
System.out.println(q.poll());
// 从头获取元素,不刪除该元素
System.out.println(q.peek());
// 获取总长度
System.out.println(q.size());
输出:张三
李四
3
8:BlockingQueue
阻塞队列是线程安全的。 在队列为空时,获取元素的线程会等待队列变为非空。 当队列满时,存储元素的线程会等待队列可用。
add(E e)
加入队列的尾部,在成功时返回 true,如果此队列已满,则抛出IllegalStateException;
offer(E e)
加入队列的尾部,在成功时返回 true,如果此队列已满,,则返回 false。
offer(E e, long timeout, TimeUnit unit)
将指定的元素插入此队列的尾部,如果该队列已满,则在到达指定的等待时间之前等待可用的空间。
(1)ArrayBlockingQueue:
ArrayBlockingQueue array = new ArrayBlockingQueue(3);
array.add("张三");//添加成功返回true,队列已满,则抛出IllegalStateException
array.add("李四");
array.add("大圣");
boolean a=array.offer("王五",1, TimeUnit.SECONDS);添加成功返回true。队列已满,等待时间,超时后返回false,
System.out.println(a);
//输出:false
(2)LinkedBlockingQueue
LinkedBlockingQueue lbq = new LinkedBlockingQueue(3);//初始化容量为3,如果不设置初始值,Integer.MAX_VALUE
lbq.add("张三");
lbq.add("李四");
lbq.add("李四");
System.out.println(lbq.size()); //输出结果:3
(3)PriorityBlockingQueue
没有限制,在内存允许的情况下可以无限添加元素;它又是具有优先级的队列,是通过构造函数传入的对象来判断,传入的对象必须实现comparable接口
class Person implements Comparable<Person>{
private int id;
private String name;
@Override
public int compareTo(Person person) {
return this.id > person.getId() ? 1 : ( this.id < person.getId() ? -1 :0);
}
}
public class Test1 {
public static void main(String[] args) throws InterruptedException {
PriorityBlockingQueue<Person> pbq = new PriorityBlockingQueue<>();
pbq.add(new Person(3,"person3"));
System.err.println("队列为:" + pbq);
pbq.add(new Person(2,"person2"));
System.err.println("队列为:" + pbq);
pbq.add(new Person(1,"person1"));
System.err.println("队列为:" + pbq);
pbq.add(new Person(4,"person4"));
System.err.println("队列为:" + pbq);
按照升序列添加
}
}
(4)SynchronousQueue
仅允许容纳一个元素。当一个线程插入一个元素后会被阻塞,除非这个元素被另一个线程消费
SynchronousQueue<Integer> queue = new SynchronousQueue<Integer>();
queue.put(1);
queue.take();
抛异常 | 正常 | 阻塞 | 超时 | |
插入 | add(e) | offer(e) | put(e) | offer(e, time, unit) |
移除 | remove() | poll() | take() | poll(time, unit) |
检查 | element() | peek() | 不可用 | 不可用 |