亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

使用線程生產和消費到列表?

使用線程生產和消費到列表?

蠱毒傳說 2022-06-23 16:55:59
我創建了兩個單獨的線程,一個用于寫入列表,第二個用于從列表中刪除。package com.produ.consu;public class Test {    public static void main(String[] args) {        Operations operations = new Operations();        Runnable r1 = new ThreadsClass(operations);        Runnable r2 = new ThreadsClass(operations);        Thread t1 = new Thread(r1);        Thread t2 = new Thread(r2);        t1.setName("READ");        t2.setName("WRITE");        t1.start();        t2.start();    }}以上是我創建線程的測試類。package com.produ.consu;public class ThreadsClass implements Runnable {    Operations operations;    ThreadsClass(Operations operations){        this.operations=operations;    }    @Override    public void run() {        // TODO Auto-generated method stub        if(Thread.currentThread().getName().equals("WRITE")) {            operations.writeList();        }        else {            operations.readList();        }    }}以上是基于線程名稱調用同步方法的類:import java.util.ArrayList;import java.util.List;public class Operations {    List<Integer> list=null;    int count=0;        boolean flag;    Operations(){        list=new ArrayList<>();        flag=true;    }    public  synchronized void writeList() {        // TODO Auto-generated method stub        while(true) {            if(flag) {                count++;                list.add(count);                System.out.println("inise if block...."+Thread.currentThread().getName());                System.out.println(list);                flag=false;                try {                    wait();                } catch (InterruptedException e) {                    // TODO Auto-generated catch block                    e.printStackTrace();                }            }            else {                notify();            }        }    }上面是我提到功能的地方。 所以寫線程必須將元素寫入列表并等待它被第二個線程刪除。一旦刪除第二個應該通知第一個并等待直到元素插入。但是得到...inise if block....寫 [1]甚至沒有被刪除,它必須是一個連續的過程。給我關于給定代碼的建議。
查看完整描述

3 回答

?
HUH函數

TA貢獻1836條經驗 獲得超4個贊

您也應該wait()在else塊內,否則while如果不滿意,它將繼續運行if并且其他線程將沒有機會執行。


執行讀/寫操作后,線程應調用notify以喚醒另一個線程,并且本身應進入等待狀態。


 public synchronized void writeList() {

      while (true) {

            if (flag) {

                count++;

                list.add(count);

                System.out.println("inise if block...." + Thread.currentThread().getName());

                System.out.println(list);

                flag = false;

                try {

                    notify(); //notify the read thread that write is complete

                    wait();   // go into the waiting state so that no further write is done until the current element is removed by the read thread.

                } catch (InterruptedException e) {

                    e.printStackTrace();

                }

            } else {

                try {

                    wait(); //wait in else, otherwise while will run endlessly

                } catch (InterruptedException e) {

                    e.printStackTrace();

                }

           }

      }

 }


 public synchronized void readList() {

        while (true) {

            System.out.println("in read");

            if (!flag) {

                Integer i = list.remove(0);

                System.out.println(i + "..removed at index by" + Thread.currentThread().getName());

                flag = true;

                try {

                    notify(); //notify write thread that read is complete

                    wait();   //go into wait until new element is inserted

                } catch (InterruptedException e) {

                    e.printStackTrace();

                }

            } else {

                try {

                    wait(); //wait in else otherwise while runs endlessly

                } catch (InterruptedException e) {

                    e.printStackTrace();

                }

            }

        }

    }


查看完整回答
反對 回復 2022-06-23
?
茅侃侃

TA貢獻1842條經驗 獲得超22個贊

您應該用更細粒度的同步替換方法同步:使用同步塊包裝訪問列表和更新計數的操作。

或者,使用鏈接阻塞隊列在線程之間傳遞“消息”(或者,在更高級的場景中,使用 Akka、Kafka、zeromq 等消息傳遞解決方案或其他類似解決方案)


查看完整回答
反對 回復 2022-06-23
?
紅糖糍粑

TA貢獻1815條經驗 獲得超6個贊

由于您一次只添加一個元素,因此您也可以使用 Exchanger??匆幌?Java 并發包。


import java.io.IOException;

import java.util.concurrent.Exchanger;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

import java.util.concurrent.TimeUnit;


public class Foo {


    public static void main(String[] args) throws IOException, InterruptedException {


        final Exchanger<Integer> exchanger = new Exchanger<>();    

        ExecutorService executorService = Executors.newCachedThreadPool();


        executorService.execute(() -> {

            // producer

            int count = 0;

            while (!Thread.currentThread().isInterrupted()) {

                try {

                    exchanger.exchange(count++);

                } catch (InterruptedException e) {

                    Thread.currentThread().interrupt();

                }

            }

        });


        executorService.execute(() -> {

            // reader

            while (!Thread.currentThread().isInterrupted()) {

                try {

                    System.out.println("consume " + exchanger.exchange(null));

                } catch (InterruptedException e) {

                    Thread.currentThread().interrupt();

                }

            }

        });


        System.in.read();


        executorService.shutdownNow();

        executorService.awaitTermination(10, TimeUnit.SECONDS);

        System.out.println("Shut down");

    }

}


查看完整回答
反對 回復 2022-06-23
  • 3 回答
  • 0 關注
  • 113 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號