Java中多線程通信怎么實現


線程通信的方式:

  1、共享變量

      線程間通信可以通過發送信號,發送信號的一個簡單方式是在共享對象的變量里設置信號值。線程A在一個同步塊里設置boolean型成員變量hasDataToProcess為true,線程B也在同步代碼塊里讀取hasDataToProcess這個成員變量。這個簡單的例子使用了一個持有信號的對象,並提供了set和get方法。

  

public class MySignal1 {
    //共享的變量
    private boolean hasDataToProcess = false;

    //取值
    public boolean getHasDataProcess() {
        return hasDataToProcess;
    }

    //存值
    public void setHasDataToProcess(boolean hasDataToProcess) {
        this.hasDataToProcess = hasDataToProcess;
    }

    public static void main(String[] args) {
        //同一個對象
        final MySignal1 my = new MySignal1();
        //線程1設置hasDataToProcess值為true
        final Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                my.setHasDataToProcess(true);
            }
        });
        t1.start();
        //線程2取這個值hasDataToProcess
        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    //等待線程1完成后取值
                    t1.join();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                my.getHasDataProcess();
                System.out.println("t1改變以后的值:"+my.getHasDataProcess());
            }
        });
        t2.start();
    }
}

運行結果如下:

  

t1改變以后的值:true

 

  2、等待/喚醒(wait/notify)機制

     以資源為例,生產者生產一個資源,通知消費者就消費掉一個資源,生產者繼續生產資源,消費者消費資源,以此循環,代碼如下。

import sun.security.util.Password;

//資源類
class Resource {
    private String name;
    private int count = 1;
    private boolean flag = false;

    public synchronized void set(String name) {
        //生產資源
        while (flag) {
            try {
                //線程等待
                wait();
            } catch (InterruptedException e) {
            }
        }
        this.name = name + "----" + count + "+++++";
        System.out.println(Thread.currentThread().getName() + "..生產者..." + this.name);
        flag = true;
        //喚醒等待中的消費者
        this.notifyAll();
    }

    public synchronized void out() {
        //消費資源
        while (!flag) {
            try {
                //線程等待,生產者生產資源
                wait();
            } catch (InterruptedException e) {
            }
        }
        System.out.println(Thread.currentThread().getName() + "...消費者..." + this.name);
        flag = false;
        //喚醒消費者,生產資源
        this.notifyAll();
    }
}

//生產者
class Producer implements Runnable {
    private Resource rs;

    public Producer(Resource rs) {
        this.rs = rs;
    }

    //生產者生產資源
    @Override
    public void run() {
        while (true) {
            rs.set("商品");
        }
    }
}

//消費者消費資源
class Consumer implements Runnable {
    private Resource rs;

    public Consumer(Resource rs) {
        this.rs = rs;
    }

    //消費者消費資源
    @Override
    public void run() {
        while (true) {
            rs.out();
        }
    }
}

public class ProducerConsumerDemo {
    public static void main(String[] args) {
        Resource r = new Resource();
        Producer p = new Producer(r);
        Consumer c = new Consumer(r);
        Thread t1 = new Thread(p);
        Thread t2 = new Thread(c);
        t1.start();
        t2.start();
    }
}

運行結果如下:

Thread-0..生產者...商品----1+++++
Thread-1...消費者...商品----1+++++
Thread-0..生產者...商品----1+++++
Thread-1...消費者...商品----1+++++
Thread-0..生產者...商品----1+++++
Thread-1...消費者...商品----1+++++
Thread-0..生產者...商品----1+++++

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM