Fork me on GitHub

并发编程

并发编程

并发编程是任何语言在项目中都会使用的方式,这里就以Java的语言来实现并发编程。并发编程的线程安全是我们需要关注的重点

实现线程的方式

  • 实现Callable和Future
  • 实现Runnable
  • Thread的匿名Runnable

CountDownLatch

class CountRunnable implements Runnable {
        CountDownLatch latch;

        public CountRunnable(CountDownLatch latch) {
            this.latch = latch;
        }

        @Override
        public void run() {
            //TODO  执行你的任务
            System.out.println("CountRunnable " + System.currentTimeMillis());
            try {
                Thread.sleep(100);
                latch.countDown();//减1
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
}
        CountDownLatch countDownLatch = new CountDownLatch(4);
        for (int i = 0; i < 10; i++) {
            Thread thread = new Thread(new CountRunnable(countDownLatch));
            thread.start();
        }
        countDownLatch.await();//当前线程等待CountDownLatch任务执行完成

Semaphore来同步线程

//1 允许线程可以同时访问的数量
//true 表示线程的顺序是按照次序的, false是表示线程访问是随机顺序的
Semaphore available = new Semaphore(1, true);
available.acquire();//可访问的线程数量减1
available.release();//可访问的线程数量加1

Synchronization来同步线程

  • 同步方法 public synchronized void fun() {}
  • 同步对象 public void fun() {synchronized(this){}}
    private static int t = 0;
        Object mutex = new Object();
        ExecutorService executorService = Executors.newFixedThreadPool(400);
        // The high thread count is for demonstration purposes.
        for (int i = 0; i < 100; i++) {
            executorService.execute(() -> {
                synchronized (mutex) {
                    t++;
                    System.out.println(MessageFormat.format("t: {0}", t));
                }
            });
        }
        executorService.shutdown();

synchronized+wait和notify

ReentrantLock

Lock lockObj = new ReentrantLock();
public void doSomething() {
 //其他地方的调用时 lockObj.lock();
boolean locked = lockObj.tryLock();
if (locked) {//解锁
 try {
  //TODO 
   } finally {
     lockObj.unlock(); // sure to release the lock without fail
   } 
 }
}

ReentrantLock+Condition

private final Lock lock = new ReentrantLock();
private final Condition condition = lock.newCondition();

condition.await()会释放当前锁,进入等待状态;
condition.signal()会唤醒某个等待线程;
condition.signalAll()会唤醒所有等待线程;

ReadWriteLock 读写锁

读可以多线程访问,写操作只能一个线程执行。如果有线程正在读的时候,写线程需要等待读线程释放锁后才能获取写线程,是一种悲观锁。StampedLock锁就解决了这种问题,但是会带来,读线程的在写线程的前后数据不一致,是一种乐观锁。

Concurrent包

  1. 集合
interface non-thread-safe thread-safe
List ArrayList CopyOnWriteArrayList
Map HashMap ConcurrentHashMap
Set HashSet / TreeSet CopyOnWriteArraySet
Queue ArrayDeque / LinkedList ArrayBlockingQueue / LinkedBlockingQueue
Deque ArrayDeque / LinkedList LinkedBlockingDeque
  1. Atomic类

线程的join()

不适合多线程的操作,但是如果就2个线程的话可以使用

线程池+同步线程队列

posted @ 2022-06-23 12:41  KevinAt2022  阅读(199)  评论(0)    收藏  举报