爱上Androidjs css html

Java 线程间通信

2022-09-07  本文已影响0人  Tinyspot

1. 线程之间如何通信

1.2 阻塞

2. wait() / notify() / notifyAll()

2.1 wait()

public class Demo {
    // 声明为 final, 表示引用不可变,若引用变了,synchronized 锁的就是不同对象
    static final Object obj = new Object();
    public static void main(String[] args) throws InterruptedException {
        obj.wait();
    }
}

运行会抛异常 Exception in thread "main" java.lang.IllegalMonitorStateException,因为此时并未获得锁

public class Demo {
    static final Object obj = new Object();
    public static void main(String[] args) throws InterruptedException {
        synchronized (obj) {
            obj.wait();
        }
    }
}

使用 synchronized 先获得锁,成为该锁的 owner, 然后再调用 wait()

2.2 wait(long n)

有时限的等待,到 n 毫秒后结束等待,或被 notify()

    public final void wait() throws InterruptedException {
        wait(0);
    }

    public final native void wait(long timeout) throws InterruptedException;
    public final void wait(long timeout, int nanos) throws InterruptedException {}

示例

static final Object obj = new Object();
public static void main(String[] args) {
    new Thread(() -> {
        synchronized (obj) {
            log.debug("start...");
            try {
                obj.wait(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            log.debug("do something...");
        }
    }).start();
}

2.3 notify() / notifyAll()

@Slf4j
public class Demo {

    static final Object obj = new Object();

    public static void main(String[] args) throws InterruptedException {
        new Thread(() -> {
            synchronized (obj) {
                log.debug("run...");
                try {
                    obj.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                log.debug("do something...");
            }
        }).start();

        new Thread(() -> {
            synchronized (obj) {
                log.debug("run...");
                try {
                    obj.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                log.debug("do something...");
            }
        }).start();

        TimeUnit.SECONDS.sleep(1);
        synchronized (obj) {
            // obj.notify();
            obj.notifyAll();
        }
    }
}

3. wait() vs sleep()

public class Thread implements Runnable {
    public static native void sleep(long millis) throws InterruptedException;
}

public class Object {
    public final native void wait(long timeout) throws InterruptedException;
}

3.1 验证 sleep() 不释放锁

@Slf4j
public class Demo {
    static final Object obj = new Object();
    public static void main(String[] args) throws InterruptedException {
        new Thread(() -> {
            synchronized (obj) {
                log.debug("start...");
                try {
                    TimeUnit.SECONDS.sleep(3);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                log.debug("do something...");
            }
        }).start();

        TimeUnit.SECONDS.sleep(1);

        // main 线程想获取锁,并执行逻辑
        synchronized (obj) {
            log.debug("run...");
        }
    }
}

执行结果

22:16:16.687 [Thread-0] DEBUG com.example.concrete.Demo - start...
22:16:19.691 [Thread-0] DEBUG com.example.concrete.Demo - do something...
22:16:19.691 [main] DEBUG com.example.concrete.Demo - run...
上一篇下一篇

猜你喜欢

热点阅读