先检查再执行,必须保证原子性 :if(condition(a)){ handle(a);}
StringBuilder ->StringBuffer
SimpleDateFormat -> JodaTime
ArrayList,HashSet,HashMap等Collections
ArrayList -> Vector,Stack
HashMap -> HashTable(Key,Value不能为null)
Collections.synchronizedXXX(List,Set,Map)
ArrayList -> CopyOnWriteArrayList
适合读多写少的场景
读在原数组上读,不需要加锁
CopyOnWriteArrayList 的 设计思想
1、读写分离 2、最终一致性 3、使用时另外开辟空间,解决并发冲突
--------------------------------------------------------------------------------------------------
HashSet ,TreeSet ->CopyOnWriteArraySet ,ConcurrentSkipListSet
HashMap,TreeMap -> ConcurrentHashMap,ConcurrentSkipListMap
=============================================================================
子类通过继承并通过实现它的方法管理其状态(acquire和release)的方法操纵状态
可以同时实现排它锁和共享锁模式(独占,共享)
package com.example.concurrency.example.aqs;
package com.example.concurrency.example.aqs;
import java.util.concurrent.*;
public class SemaphoreExample {
public static final int threadCount = 100;
public static void main(String[] args) throws InterruptedException {
ExecutorService service = Executors.newCachedThreadPool();
final CountDownLatch latch = new CountDownLatch(threadCount);
final Semaphore semaphore = new Semaphore(20);
for(int i=0;i {
try {
//也可以同时获取多个许可和释放多个许可。那样就相当于单线程了
semaphore.acquire();//获取一个许可
test(threadnum);
semaphore.release();//释放一个许可
/* if(semaphore.tryAcquire()) {//尝试获取一个许可,获取不到就不执行
test(threadnum);
semaphore.release();//释放一个许可
}else {
System.out.println("丢弃");
}*/
} catch (InterruptedException e) {
System.out.println(e.getMessage());
}finally {
latch.countDown();
}
});
}
latch.await(10, TimeUnit.MILLISECONDS);
System.out.println("finish");
service.shutdown();
}
private static void test(int i) throws InterruptedException {
Thread.sleep(100);
System.out.println(i);
}
}
public class CyclicBarrierExample2 {
static CyclicBarrier barrier = new CyclicBarrier(5);
public static void main(String[] args) throws InterruptedException {
ExecutorService service = Executors.newCachedThreadPool();
for (int i = 0; i < 10; i++) {
final int threadNum = i;
Thread.sleep(1000);
service.execute(() -> {
try {
race(threadNum);
} catch (Exception e) {
System.out.println("exception");
}
});
}
service.shutdown();
}
private static void race(int i) throws Exception {
Thread.sleep(1000);
System.out.println(i + " is ready");
//尽可能多的捕获一些异常,捕捉完异常并不会影响后续代码的执行
try {
barrier.await(2000, TimeUnit.MILLISECONDS);//支持等待时间
}catch (InterruptedException | TimeoutException |BrokenBarrierException e){
System.out.println(i+" exception");
}
System.out.println(i+" is continue");
}
}
ReenTrantLock(可重入锁)和synchronized区别
1)可重入性
2)锁的实现
3)性能的区别
4)功能区别
ReenTrantLock 独有的功能
1)可指定是公平锁还是非公平锁
提供了一个Condition类,可以分组唤醒需要唤醒的线程
提供能够中断等待锁的线程的机制 lock.lockInterruptibly()
@ThreadSafe
public class LockExample {
public static int threadTotal=200;
public static final int clientTotal = 5000;
public static int count = 0;
public static Lock lock = new ReentrantLock();
public static void main(String[] args) throws InterruptedException {
final ExecutorService service = Executors.newCachedThreadPool();
final Semaphore semaphore = new Semaphore(threadTotal);
CountDownLatch latch = new CountDownLatch(clientTotal);
for(int i=0;i
@ThreadSafe
public class LockExample1 {
private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
private final Lock readLock = lock.readLock();
private final Lock writeLock = lock.writeLock();
private final Map map = new TreeMap<>();
public Data get(String key){
readLock.lock();
try{
return map.get(key);
}finally {
readLock.unlock();
}
}
public Set getAllKeys(){
readLock.lock();
try{
return map.keySet();
}finally {
readLock.unlock();
}
}
public Data put(String key,Data data){
writeLock.lock();
try{
return map.put(key,data);
}finally {
writeLock.unlock();
}
}
class Data {
}
}
@ThreadSafe
public class LockExample2 {
class Point {
private double x, y;
private final StampedLock sl = new StampedLock();
void move(double deltaX, double deltaY) { // an exclusively locked method
long stamp = sl.writeLock();
try {
x += deltaX;
y += deltaY;
} finally {
sl.unlockWrite(stamp);
}
}
/**
* 乐观读锁案例
* @return
*/
double distanceFromOrigin() { // A read-only method
long stamp = sl.tryOptimisticRead();//获得一个乐观读锁
double currentX = x, currentY = y;//将两个字段读入本地局部变量
if (!sl.validate(stamp)) {//检查发出乐观读锁后,同时是否有其他写锁发生
stamp = sl.readLock();//如果没有,我们再次获得一个读悲观锁
try {
currentX = x;//将两个字段读入本地局部变量
currentY = y;//将两个字段读入本地局部变量
} finally {
sl.unlockRead(stamp);
}
}
return Math.sqrt(currentX * currentX + currentY * currentY);
}
/**
* 悲观读锁案例
* @param newX
* @param newY
*/
void moveIfAtOrigin(double newX, double newY) { // upgrade
// Could instead start with optimistic, not read mode
long stamp = sl.readLock();
try {
while (x == 0.0 && y == 0.0) {//循环,检查当前状态是否符合
long ws = sl.tryConvertToWriteLock(stamp);//将读锁转为写锁
if (ws != 0L) {//这是确认转为写锁是否成功
stamp = ws;//如果成功,替换票据
x = newX;//进行状态改变
y = newY;//进行状态改变
break;
} else {//如果不能成功转换为写锁
sl.unlockRead(stamp);//我们显示释放读锁
stamp = sl.writeLock();//显示直接进行写锁 然后再通过循环再试
}
}
} finally {
sl.unlock(stamp);//释放读锁或写锁
}
}
}
}
public class LockExample4 {
public static void main(String[] args) {
ReentrantLock lock = new ReentrantLock();
Condition condition = lock.newCondition();
new Thread() {
@Override
public void run() {
try {
lock.lock();
System.out.println("wait single");
condition.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("get a single");
lock.unlock();
}
}.start();
new Thread() {
@Override
public void run() {
lock.lock();
System.out.println("get lock");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
condition.signalAll();
System.out.println("send single");
lock.unlock();
}
}.start();
}
}
Callable与Runnable接口对比
Future接口
FutureTask类
public class FutureExample {
static class MyCallable implements Callable{
@Override
public String call() throws Exception {
System.out.println("do sth");
Thread.sleep(5000);
return "done";
}
}
public static void main(String[] args) throws ExecutionException, InterruptedException {
ExecutorService service = Executors.newCachedThreadPool();
Future future = service.submit(new MyCallable());
System.out.println("do sth in main");
Thread.sleep(1000);
String result = future.get();
System.out.println(result);
}
}
public class FutureTaskExample {
public static void main(String[] args) throws InterruptedException, ExecutionException {
FutureTask futureTask = new FutureTask<>(new Callable() {
@Override
public String call() throws Exception {
System.out.println("do sth in call");
Thread.sleep(5000);
return ("done");
}
});
new Thread(futureTask).start();
System.out.println("do sth in main");
Thread.sleep(1000);
String result = futureTask.get();
System.out.println(result);
}
}
ForkJoin框架 ====待学习