Thread Pool

异步执行的代码

new Thread(r).start();

统一的工具类,定一个接口来实现。

public interface Executor {
    public void execute(Runnable r);
}
// 新线程:直接创建一个新线程运行
class FlashExecutor implements Executor {
    public void execute(Runnable r) {
        new Thread(r).start();
    }
}

a Lock Based on ReentrantLock

基于 ReentrantLock实现一个锁

package aqsLock;

import java.util.concurrent.locks.AbstractQueuedSynchronizer;


/**
 * @Author: Kayleh
 * @Date: 2021/4/20 0:57
 */
public class aqsLock
{
    public void lock()
    {
        sync.acquire(1);
    }

    public void unlock()
    {
        sync.release(1);
    }

    private final Sync sync = new Sync();

    public static class Sync extends AbstractQueuedSynchronizer
    {
        @Override
        protected boolean tryAcquire(int arg)
        {
            // CAS 方式尝试获取锁,成功返回true,失败返回false
            if (compareAndSetState(0, 1))
                return true;
            return false;
        }

        @Override
        protected boolean tryRelease(int arg)
        {
            // 释放锁
            setState(0);
            return true;
        }
    }
}

基本功能实现,测试:

// 可能发生线程安全问题的共享变量
private static long count = 0;

// 两个线程并发对 count++
public static void main(String[] args) throws Exception {
    // 创建两个线程,执行add()操作
    Thread th1 = new Thread(()-> add());
    Thread th2 = new Thread(()-> add());
    // 启动两个线程
    th1.start();
    th2.start();
    // 等待两个线程执行结束
    th1.join();
    th2.join();
    // 这里应该是 20000 就对了,说明锁生效了
    System.out.println(count);
}

// 我画了一上午写出来的锁,哈哈
private static ExampleLock exampleLock = new ExampleLock();

// 循环 count++,进行 10000 次
private static void add() {
    exampleLock.lock();
    for (int i = 0; i < 10000; i++) {
        count++;
    }
    add2();
    // 没啥异常,我就直接释放锁了
    exampleLock.unlock();
}

非公平锁,因为线程抢锁不排队,纯看脸。

实现的排队获取锁,叫公平锁,因为只要有线程在排队,新来的就得乖乖去排队,不能直接抢。

CAS & AQS

CAS(Compare And Swap)原理分析

字面意思是比较和交换,先看看下面场景(A 和 B 线程同时执行下面的代码):

int i = 10;    //代码1
i = 10;        //代码2

场景 1:A 线程执行代码 1 和代码 2,然后 B 线程执行代码 1 和代码 2,CAS 成功。

场景 2:A 线程执行代码 1,此时 B 线程执行代码 1 和代码 2,A 线程执行代码 2,CAS 不成功,为什么呢?

多线程

多线程