Skip to content

join方法

  • join方法可以让主线程等待子线程结束后再继续执行
  • join方法可以传入一个timeout参数,表示最多等待timeout秒
  • join方法可以在子线程中调用,表示等待主线程结束后再继续执行
  • join方法可以在主线程中调用,表示等待其他线程结束后再继续执行
  • join方法可以在多个线程中调用,表示等待这些线程全部结束后再继续执行
  • join方法的使用示例
java
public class JoinDemo {
    public static void main(String[] args) throws InterruptedException {
        Thread thread = new Thread(() -> {
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            System.out.println("Hello from a sub thread!");
        });
        thread.start();
        thread.join();
        System.out.println("Hello from main thread!");
    }
}

synchronized

  • synchronized关键字可以用来修饰方法,也可以用来修饰代码块
  • synchronized关键字修饰方法时,表示整个方法是同步的
  • synchronized关键字修饰代码块时,需要传入一个对象作为锁
  • synchronized关键字修饰代码块时,表示代码块是同步的
  • synchronized关键字修饰代码块时,需要注意锁的范围
  • synchronized关键字修饰代码块时,需要注意锁的粒度
java
public class SynchronizedDemo {
    private int count = 0;

    public synchronized void increment() {
        count++;
    }

    public int getCount() {
        return count;
    }

    public static void main(String[] args) throws InterruptedException {
        SynchronizedDemo counter = new SynchronizedDemo();

        Thread thread1 = new Thread(() -> {
            for (int i = 0; i < 1000; i++) {
                counter.increment();
            }
        });

        Thread thread2 = new Thread(() -> {
            for (int i = 0; i < 1000; i++) {
                counter.increment();
            }
        });

        thread1.start();
        thread2.start();
        thread1.join();
        thread2.join();

        System.out.println("Final count: " + counter.getCount());
    }
}

wait/notify

  • wait方法可以使当前线程等待,直到其他线程调用notify方法唤醒它
  • wait方法必须在synchronized代码块中调用
  • wait方法会释放锁
  • notify方法可以唤醒一个等待的线程
  • notify方法必须在synchronized代码块中调用
  • notify方法不会释放锁
  • wait和notify的使用示例
  • wait被唤醒之后,会从当前行后开始执行,这样可能会引起虚假唤醒问题,所以wait始终应该在循环中使用
java
public class WaitNotifyDemo {
    private boolean flag = false;

    public synchronized void waitForFlag() throws InterruptedException {
        while (!flag) {
            wait();
        }
        System.out.println("Flag is true!");
    }

    public synchronized void setFlag() {
        flag = true;
        notify();
    }

    public static void main(String[] args) throws InterruptedException {
        WaitNotifyDemo demo = new WaitNotifyDemo();

        Thread thread1 = new Thread(() -> {
            try {
                demo.waitForFlag();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        });

        Thread thread2 = new Thread(() -> {
            demo.setFlag();
        });

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

await/signal

  • await方法可以使当前线程等待,直到其他线程调用signal方法唤醒它
  • await和signal方法必须在Lock对象的synchronized代码块中调用
  • await方法会释放锁
  • signal方法可以唤醒一个等待的线程
java
public class AwaitSignalDemo {
    private Lock lock = new ReentrantLock();
    private Condition condition = lock.newCondition();
    private boolean flag = false;

    public void waitForFlag() throws InterruptedException {
        lock.lock();
        try {
            while (!flag) {
                condition.await();
            }
            System.out.println("Flag is true!");
        } finally {
            lock.unlock();
        }
    }

    public void setFlag() {
        lock.lock();
        try {
            flag = true;
            condition.signal();
        } finally {
            lock.unlock();
        }
    }

    public static void main(String[] args) throws InterruptedException {
        AwaitSignalDemo demo = new AwaitSignalDemo();

        Thread thread1 = new Thread(() -> {
            try {
                demo.waitForFlag();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        });

        Thread thread2 = new Thread(() -> {
            demo.setFlag();
        });

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

wait和sleep的区别

  • sleep是Thread的方法,wait是Object的方法
  • sleep不会释放锁,wait会释放锁
  • 都可以被interrupted唤醒