1. 程式人生 > 其它 >Java高階--多執行緒(4) 執行緒通訊的例子

Java高階--多執行緒(4) 執行緒通訊的例子

技術標籤:Java學習

執行緒通訊的例子

執行緒通訊的例子:使用兩個執行緒列印 1-100。執行緒1, 執行緒2 交替列印

package com.chen.exer;

public class CommunicationTest {
    public static void main(String[] args) {
        Number number1 = new Number();

        Thread t1 = new Thread(number1);
        Thread t2 = new Thread(number1);

        t1.
setName("執行緒一"); t2.setName("執行緒二"); t1.start(); t2.start(); } } class Number implements Runnable { private int number = 1; @Override public void run() { while (true) { synchronized (this) { notify(); if
(number<=100){ try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + ":" + number)
; number++; try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } }else { break; } } } } }

說明:

  • 1.wait(),notify(),notifyAll()三個方法必須使用在同步程式碼塊或同步方法中。

  • 2.wait(),notify(),notifyAll()三個方法的呼叫者必須是同步程式碼塊或同步方法中的同步監視器。

    否則,會出現IllegalMonitorStateException異常

  • 3.wait(),notify(),notifyAll()三個方法是定義在java.lang.Object類中。

面試題:sleep() 和 wait()的異同?

  • 1.相同點:一旦執行方法,都可以使得當前的執行緒進入阻塞狀態。

  • 2.不同點:1)兩個方法宣告的位置不同:Thread類中宣告sleep() , Object類中宣告wait()

    ​ 2)呼叫的要求不同:sleep()可以在任何需要的場景下呼叫。 wait()必須使用在同步程式碼塊或同步方法中

    ​ 3)關於是否釋放同步監視器:如果兩個方法都使用在同步程式碼塊或同步方法中,sleep()不會釋放鎖,wait()會釋放鎖。

package com.chen.exer;

/**
 * 經典的生產者消費者問題
 * 
 * 共享資料 clerk 櫃檯  20個
 */


public class ProductTest {
    public static void main(String[] args) {
        Clerk clerk = new Clerk();

        Producter p1 = new Producter(clerk);
        p1.setName("生產者一");

        Consumer c1 = new Consumer(clerk);
        c1.setName("消費者一");

        p1.start();
        c1.start();
    }
}

class Clerk {
    private int productCount = 0;

    public synchronized void produceProduct() {
        if (productCount < 20) {
            productCount++;
            System.out.println(Thread.currentThread().getName() + ":開始生產第" + productCount + "個產品");
            notify();
        } else {
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public synchronized void ConsumeProduct() {
        if (productCount > 0) {

            System.out.println(Thread.currentThread().getName() + ":開始消費第" + productCount + "個產品");
            productCount--;
            notify();
        } else {
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

class Producter extends Thread {
    private Clerk clerk;

    public Producter(Clerk clerk) {
        this.clerk = clerk;
    }


    @Override
    public void run() {
        while(true){
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            clerk.produceProduct();
        }
    }
}

class Consumer extends Thread {
    private Clerk clerk;

    public Consumer(Clerk clerk) {
        this.clerk = clerk;
    }

    @Override
    public void run() {
        while (true) {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            clerk.ConsumeProduct();

        }
    }
}