闲谈java wait、notify、join

wait

wait()方法的作用是使当前执行代码的线程进行等待。wait()是Object类的方法,用来将当前线程置入预执行队列中,并且在wait()所在的代码处停止执行,直到接到通知或被中断为止。

wait()调用前必须获得该对象的对象级锁,只能在同步方法或者同步代码块中调用wait(),否则会抛IllegalMonitorStateException。当wait()执行后,当前线程释放锁。

notify

notify()方法的作用是用来通知那些可能等待该对象的对象锁的其他线程,如果有多个线程等待,则随机挑选出一个wait状态的线程,对其发出通知,并使它等待获取该对象的对象锁。

notify()调用前,必须获得该对象的对象级锁,即只能在同步方法或者同步代码块中调用notify()方法,否则会抛出IllegalMonitorStateException。

当notify()方法执行后,不会马上释放该对象的锁,呈wait状态的线程也并不能马上获得该对象锁,要等到执行notify()的线程将程序执行完,也就是退出synchronized代码块后,当前线程才会释放锁。

notifyAll()方法和notify()作用基本是一样的,一个是唤醒全部的wait线程,一个是唤醒其中一个wait线程。

经典案例生产者和消费者

public class MyStack {
    private List<String> list = new ArrayList<>();

    public synchronized void push() {
        try {
            while (list.size() == 5) {
                this.wait();
            }
            list.add("1");
            this.notifyAll();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    
    public synchronized String pop(){
        String returnValue = "";
        try {
            while(list.size() == 0){
                this.wait();
            }
            returnValue = list.get(0);
            list.remove(0);
            this.notifyAll();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return returnValue;
    }
}

public class Product {
    private MyStack myStack;
    public Product(MyStack myStack) {
        this.myStack = myStack;
    }
    
    public void pushService(){
        myStack.push();
    }
}

public class Customer {
    private MyStack myStack;
    public Customer(MyStack myStack) {
        this.myStack = myStack;
    }
    
    public void popService(){
        myStack.pop();
    }
}

public class ThreadCustomer extends Thread {

    private Customer customer;

    public ThreadCustomer(Customer customer) {
        this.customer = customer;
    }

    @Override
    public void run() {
        while(true){
            customer.popService();
        }
    }
}

public class ThreadProduct extends Thread {

    private Product product;

    public ThreadProduct(Product product) {
        this.product = product;
    }

    @Override
    public void run() {
        while(true){
            product.pushService();
        }
    }
}

public class Test {
    public static void main(String[] args) throws InterruptedException {
        
        MyStack myStack = new MyStack();
        Product p = new Product(myStack);
        Customer c = new Customer(myStack);
        
        ThreadProduct pThread = new ThreadProduct(p);
        ThreadCustomer cThread = new ThreadCustomer(c);
        pThread.start();
        cThread.start();
                
    }
}

join

join()是Thread类的一个方法,它的作用是使所属的线程x对象正常的执行run方法中的任务,而使当前线程z进行无限期的阻塞,等待线程x销毁后再继续执行线程z后面的代码。

public class MyThread extends Thread{
    @Override
    public void run() {
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

public class Test {
    public static void main(String[] args) throws InterruptedException {
        MyThread myThread = new MyThread();
        myThread.start();
        myThread.join();
        System.out.println("在myThread执行完后输出:" + System.currentTimeMillis());
    }
}

join和synchronized的区别

join方法具有线程排队运行的作用,有些类是同步的运行效果。join和synchronized的区别是:join在内部使用wait()方法进行等待,而synchronized是使用“对象监视器”原理同步。

join(long)和sleep(long)的区别

由于join的内部是使用wait来实现的,所以它具有释放锁的特点,而sleep没有这一特点。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值