多线程 - 9.线程的等待与唤醒

体验线程之间的交互测试
import java.util.ArrayList;
import java.util.List;

class Something{
    private List<String> list = new ArrayList<>();
    public void add() {
        list.add("xxx");
    }
    synchronized public int size() {
        return list.size();
    }
}

class ThreadA extends Thread{
    private Something something;
    public ThreadA(Something something) {
        super();
        this.something = something;
    }
    @Override
    public void run() {
        try {
            for (int i = 0; i < 10; i++) {
                something.add();
                System.out.println("添加 了" + (i + 1) + "个元素");
                Thread.sleep(1000);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

class ThreadB extends Thread{
    private Something something;
    public ThreadB(Something something) {
        super();
        this.something = something;
    }
    @Override
    public void run() {
        try {
            while(true) {
                if (something.size() == 5) {
                    System.out.println("达到 5 的时候退出线程");
                    throw new InterruptedException();
                }
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

public class test0 {
    public static void main(String[] args) {
        Something something = new Something();
        Thread a = new ThreadA(something);
        a.setName("A");
        a.start();

        Thread b = new ThreadB(something);
        b.setName("B");
        b.start();
    }
}

添加 了1个元素
添加 了2个元素
添加 了3个元素
添加 了4个元素
添加 了5个元素
达到 5 的时候退出线程
java.lang.InterruptedException
at ThreadB.run(test0.java:48)
添加 了6个元素
添加 了7个元素
添加 了8个元素
添加 了9个元素
添加 了10个元素

通过 wait() 与 notify() 函数改编
import java.util.ArrayList;
import java.util.List;

class Something{
    private static List<String> list = new ArrayList<>();
    static public void add() {
        list.add("xxx");
    }
    /*synchronized*/ static public int size() {
        return list.size();
    }
}

class ThreadA extends Thread{
    private Object lock;
    public ThreadA(Object lock) {
        super();
        this.lock = lock;
    }

    @Override
    public void run() {
        synchronized (lock) {
            if (Something.size() != 5) {
                System.out.println("wait 开始" + System.currentTimeMillis());
                try {
                    lock.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("wait 结束" + System.currentTimeMillis());
            }
        }
    }
}

class ThreadB extends Thread{
    private Object lock;
    public ThreadB(Object lock) {
        super();
        this.lock = lock;
    }

    @Override
    public void run() {
        synchronized (lock) {
            for (int i = 0; i < 10; i++) {
                Something.add();
                System.out.println("已添加"+i+"个元素");
                if (Something.size() == 5) {
                    lock.notify();
                    System.out.println("已唤醒");
                }
            }
        }
    }
}

public class test1 {
    public static void main(String[] args) {
        Something something = new Something();
        Thread a = new ThreadA(something);
        a.setName("A");
        a.start();

        Thread b = new ThreadB(something);
        b.setName("B");
        b.start();
    }
}

wait 开始1592380913162
已添加0个元素
已添加1个元素
已添加2个元素
已添加3个元素
已添加4个元素
已唤醒
已添加5个元素
已添加6个元素
已添加7个元素
已添加8个元素
已添加9个元素
wait 结束1592380913163

join() 函数的使用

方法 join() 的作用是等待线程销毁。

import java.util.Random;

class ThreadA extends Thread{

    @Override
    public void run() {
        super.run();
        try {
            System.out.println("ThreadA run start");
            Thread.sleep(new Random().nextInt(3000));
            System.out.println("ThreadA run end");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

public class test2 {
    public static void main(String[] args) {
        Thread a = new ThreadA();
        a.start();
        try {
            a.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("这句话应该等 run end 结束之后再输出");
    }
}

ThreadA run start
ThreadA run end
这句话应该等 run end 结束之后再输出

join()有唤醒、释放锁的特点,所以不要与 wait() 、 notify() 、 notifyAll()同时使用, join() 函数内部就是由 wait() 函数进行实现的。

猜你喜欢

转载自blog.csdn.net/weixin_43845524/article/details/106810040