并发编程笔记2

交替输出事例

@Slf4j
public class Demo02 {
    public static void main(String[] args) {
        Await await = new Await(5);
        Condition a = await.newCondition();
        Condition b = await.newCondition();
        Condition c = await.newCondition();
        new Thread(()->{
            await.print("a",a,b);
        },"t1").start();
        new Thread(()->{
            await.print("b",b,c);
        },"t2").start();
        new Thread(()->{
            await.print("c",c,a);
        },"t3").start();
        await.lock();
        a.signal();
        await.unlock();

    }


}
@Slf4j
class Await extends ReentrantLock{
    private int num;

    public Await(int num) {
        this.num = num;
    }
    public void print(String str, Condition condition, Condition next){
        for (int i = 0; i < num; i++) {
            lock();
            try {
                condition.await();
                log.info("打印{}",str);
                next.signal();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                unlock();
            }
        }

    }
}

可见性

停不下来的循环

static boolean run = true;

    public static void main(String[] args) throws InterruptedException {
        Thread t = new Thread(() -> {
            while (run) {
            }
        });
        t.start();
        sleep(1);
        run = false; // 线程t不会如预想的停下来
    }

image
解决方案
volatile(易变关键字)
它可以用来修饰成员变量和静态成员变量,他可以避免线程从自己的工作缓存中查找变量的值,必须到主存中获取它的值,线程操作 volatile 变量都是直接操作主存
也可以使用synchronize进行加锁解决。
volatile可以改进之前的两阶段终止模式。进行打断标记的判断。private volatile boolean stop = false;

有序性

JVM 会在不影响正确性的前提下,可以调整语句的执行顺序,思考下面一段代码
image
cpu指令重排可以提高运行效率,将不同的指令交给不通的处理器

原理略

以后需要的时候再看这些八股文
先暂时不看了

hmoban主题是根据ripro二开的主题,极致后台体验,无插件,集成会员系统
自学咖网 » 并发编程笔记2