Java多線程技術-wait/notify/join,-waitnotify

來源:互聯網
上載者:User

Java多線程技術-wait/notify/join,-waitnotify
wait/notify的作用

wait()方法的作用是使當前執行代碼的線程進行等待,wait()是Object類的方法,用來將當前線程置入預執行隊列中,並且在wait()所在的代碼處停止執行,直到接到通知或被中斷為止。wait()調用前,必須獲得該對象的對象級鎖,即只能在同步方法或者同步代碼塊中調用wait()方法,否則會拋出IllegalMonitorStateException。當wait()執行後,當前線程釋放鎖

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() == 1) {                System.out.println("push:"+Thread.currentThread().getName()+"呈wait狀態");                this.wait();            }            list.add("anyString=" + Math.random());            this.notifyAll();            System.out.println("push=" + list.size());        } catch (InterruptedException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }    }        public synchronized String pop(){        String returnValue = "";        try {            while(list.size() == 0){                System.out.println("pop:"+Thread.currentThread().getName()+"呈wait狀態");                this.wait();            }            returnValue = list.get(0);            list.remove(0);            this.notifyAll();            System.out.println("pop="+list.size());        } catch (InterruptedException e) {            // TODO Auto-generated catch block            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();                    }}
View Code

 

join的作用

join()是Thread類的一個方法,它的作用是使所屬的線程x對象正常的執行run方法中的任務,而使當前線程z進行無限期的阻塞,等待線程x銷毀後再繼續執行線程z後面的代碼。

public class MyThread extends Thread{    @Override    public void run() {        try {            System.out.println(System.currentTimeMillis());            Thread.sleep(3000);        } catch (InterruptedException e) {            // TODO Auto-generated catch block            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());    }}
View Code

測試結果:

1516170164683在myThread執行完後輸出:1516170167686
join和synchronized的區別

從上面的例子可以看出,join方法具有線程排隊啟動並執行作用,有些類是同步的運行效果。join和synchronized的區別是:join在內部使用wait()方法進行等待,而synchronized是使用“對象監視器”原理做為同步

join(long)和sleep(long)的區別

由於join的內部是使用wait來實現的,所以它具有釋放鎖的特點,而sleep沒有這一特點。

源碼如下:

 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;            }        }    }

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.