ReentrantLock
重入锁
可中断
可限时: tryLock(等待的时间,时间的大小)
公平锁:ReentrantLock(boolean fair)Condition
await(),线程等待
signal(),唤醒线程Semaphore()
允许多个线程同时进行操作
package dayfirst;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
public class SemapDemo implements Runnable{
final Semaphore semp = new Semaphore(5);
@Override
public void run() {
try {
semp.acquire();
Thread.sleep(2000);
System.out.println(Thread.currentThread().getId()+"done");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
semp.release();
}
}
public static void main(String[] args) {
ExecutorService exec =
Executors.newFixedThreadPool(20);
final SemapDemo demo = new SemapDemo();
for(int i = 0; i < 20; i++) {
exec.submit(demo);
}
}
}
ReadWriteLock
读写锁: 读写互斥,写写互斥,但是读读不互斥。
CyclicBarrier
将计数器设置为10,那么凑齐满一批10个线程后,计数器就会归0,然后接着凑齐下一批10个线程。
package dayfirst;
import java.util.Random;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
public class CyclicBarrierDemo {
public static class Soldier implements Runnable{
private String soldier;
private CyclicBarrier cyclic = null;
Soldier(CyclicBarrier cyclic, String soldier){
this.cyclic = cyclic;
this.soldier = soldier;
}
@Override
public void run() {
try {
cyclic.await();//等待所有士兵到齐
doWork();
cyclic.await();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (BrokenBarrierException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private void doWork() {
try {
Thread.sleep(Math.abs(new Random().nextInt()%10000));
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(soldier + ":任务完成");
}
}
public static class BarrierRun implements Runnable{
boolean flag;
int N;
public BarrierRun(boolean flag, int N) {
this.flag = flag;
this.N = N;
}
@Override
public void run() {
if(flag) {
System.out.println("司令:任务完成");
}else {
System.out.println("司令:集合完毕");
flag = true;
}
}
}
public static void main(String[] args) {
final int N = 10;
Thread[] allSoldier = new Thread[N];
boolean flag = false;
CyclicBarrier cyclic = new CyclicBarrier(N, new BarrierRun(flag, N));
//设置障碍点
System.out.println("集合队伍");
for(int i = 0; i < N; i++) {
System.out.println("士兵"+i+"报道");
allSoldier[i] = new Thread(new Soldier(cyclic, "士兵"+i));
allSoldier[i].start();
}
}
}
- LockSupport
提供线程阻塞原语
park():挂起线程
unpark()继续执行
重入锁实现
CAS状态
判断一个数据是不是可以被修改
等待队列
内部维护的一个队列
park()
每一个线程进入队列后,都要park()一下,出队列后unpark()一下
并发容器的实现
- HashMap
- List
Set
线程不安全,需要用Collenctions.synchronizedMap(new HashMap());进行包装等
内部实现
public static <K,V> Map<K,V> synchronizedMap(Map<K,V> m) {
return new SynchronizedMap<>(m); //将传入进去的map进行封装
}
public int size() {
synchronized (mutex) {return m.size();}
}
public boolean isEmpty() {
synchronized (mutex) {return m.isEmpty();}
}
每一个方法都用synchronized关键字修饰,所以get和put方法都会有线程等待,因此造成的并发量不高。不适合高并发。
- ConcurrentHashMap内部实现
put()方法操作
public V put(K key, V value){
Segment<K,V> s;
if(value == null)
throws new NullPointerException();
int hash = hash(key);
int j = (hash >>> segmentShift) & segmentMask;
if((s = (Segment<K,V>)UNSAFE.getObject
(segments, (j << SSHIFT) + SBASE)) == null)
s = ensureSegment(j);
return s.put(key, hash, value, false);
}