虚假唤醒

介绍:

一个线程可以从挂起状态变为可运行状态(也就是被唤醒),即使该线程没有被其他线程调用notify()、notifyall()方法进行通知,或者被中断,或者等待超时;

解决:

不停的去测试该线程是否满足条件,不满足则继续等待;
synchronized(obj){
    while(条件不满足){
        obj.wait();
    }
}

join与yield的异同

join

  • 一个线程在运行的过程中,临时加入另外一个线程,等待新加入的线程运算完之后,旧的线程再继续执行;
  • 旧的线程处理阻塞状态;

源码:

public final synchronized void join(long millis)
    throws InterruptedException {
        long base = System.currentTimeMillis();
        long now = 0;

        if (millis < 0) {
            throw new IllegalArgumentException("timeout value is negative");
        }

        if (millis == 0) {
            while (isAlive()) {
                //等待
                wait(0);
            }
        } else {
            while (isAlive()) {
                long delay = millis - now;
                if (delay <= 0) {
                    break;
                }
                wait(delay);
                now = System.currentTimeMillis() - base;
            }
        }
    }

实例:加入的线程全部执行完毕之后,旧的线程才继续执行;

/**
 * @author SHshuo
 * @data 2021/9/4--20:22
 * join的概念:
 * 当我们在进行多线程运算的时候,一个线程在运行的过程中。
 * 我们可以临时加入另外一个线程,让新加入的线程运算完之后,旧的线程再继续执行。旧的线程处于阻塞状态。
 */
public class joinTest {
    public static void main(String[] args) throws InterruptedException {

        Thread thread1 = new Thread(() -> {
            for (int i = 0; i < 20; i++) {
                System.out.println(Thread.currentThread().getName() + "=>" + i);
            }
        },"A");

        Thread thread2 = new Thread(() -> {
            for (int i = 0; i < 20; i++) {
                System.out.println(Thread.currentThread().getName() + "=>" + i);
            }
        },"B");

        thread1.start();
//        正常是A、B交替执行,加入join相当于插入A,会等到A全部执行完毕,B才执行
        thread1.join();
        thread2.start();
    }
}


yield

  • 可以将当前线程的执行权限让出来:Running(运行) -> Runnable(就绪)。只是礼让一下,仍有可能交替执行;
  • 就绪状态:是指该线程已经获得了除了CPU资源外的其他资源,等到获取CPU资源后才会真正处于运行状态;

源码:

public static native void yield();

实例:新加入的线程与旧的线程交替执行

/**
 * @author SHshuo
 * @data 2021/9/4--20:22
 * yield概念: 可以将当前的线程的执行权限让出来,Running(运行) -> Runnable(就绪)。
 * 只是礼让一下,仍有可能交替执行。
 */
public class yieldTest {
    public static void main(String[] args) {
        Thread thread1 = new Thread(() -> {
            for (int i = 0; i < 20; i++) {
                System.out.println(Thread.currentThread().getName() + "=>" + i);
//                A线程会礼让B线程一下,A处于就绪状态之后又与B线程交替执行
                Thread.yield();
            }
        },"A");

        Thread thread2 = new Thread(() -> {
            for (int i = 0; i < 20; i++) {
                System.out.println(Thread.currentThread().getName() + "=>" + i);
            }
        },"B");

        thread1.start();
        thread2.start();
    }
}

伪共享

涉及OS的内容具体查看本博客的链接:
https://blog.nowcoder.net/n/f6c3f2facf2b41f6989fd93580db7294