簡體   English   中英

順序寫入和讀取(兩個線程)

[英]Sequential writing and reading (two threads)

該主題在此處繼續: https : //codereview.stackexchange.com/q/249978/231182

我是 Java 編程語言的新手。
任務:創建實現Runnable接口的SequentalWriterSequentalReader類。 它們必須提供一系列寫-讀操作(即寫-讀-寫-讀-寫-讀等)。
我想知道這個實現是否正確或需要更改什么? 此外,也歡迎小錯誤和錯誤。

import java.lang.Thread;
import vectors.Array; /* My array implementation */
import vectors.CircularLinkedList; /* My list implementation */
import vectors.IVector; /* The interface that Array and CircularLinkedList implement */

public class Task7Part2 {
    volatile int a = 0;

    public static void main(String[] args) {
        IVector arr1 = new Array(2);
        System.out.print("[Test] arr1: "); arr1.print();
        Keeper keeperArr1 = new Keeper(arr1);
        SequentalWriter seqWriter = new SequentalWriter(keeperArr1);
        SequentalReader seqReader = new SequentalReader(keeperArr1);
        (new Thread(seqWriter)).start();
        (new Thread(seqReader)).start();

        // Задержка
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            System.out.println(e.getMessage());
        }

        IVector arr2 = new Array(3);
        System.out.print("[Test] arr2: "); arr2.print();
        Keeper keeperArr2 = new Keeper(arr2);
        seqWriter = new SequentalWriter(keeperArr2);
        seqReader = new SequentalReader(keeperArr2);
        (new Thread(seqWriter)).start();
        (new Thread(seqReader)).start();

        // Задержка
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            System.out.println(e.getMessage());
        }

        IVector list = new CircularLinkedList(4);
        System.out.print("[Test] list: "); list.print();
        Keeper keeperList = new Keeper(list);
        seqWriter = new SequentalWriter(keeperList);
        seqReader = new SequentalReader(keeperList);
        (new Thread(seqWriter)).start();
        (new Thread(seqReader)).start();
    }

    public static class Keeper {
        public volatile IVector vector;
        public volatile boolean isWrite;

        public Keeper(IVector vector) {
            this.vector = vector;
            this.isWrite = true;
        }
    }

    public static class SequentalWriter implements Runnable {
        public SequentalWriter(Keeper keeper) {
            this.keeper = keeper;
        }

        public void run() {
            try {
                for (int i = 0, size = keeper.vector.size(); i < size; ++i) {
                    double d = Math.random();
                    synchronized(keeper) {
                        while (!keeper.isWrite) {
                            keeper.wait();
                        }
                        keeper.vector.set(i, d);
                        System.out.println("Write: " + d + " to position " + i);
                        keeper.isWrite = false;
                        keeper.notify();
                    }
                }
            } catch (Exception e) {
                System.out.println(e.toString());
            }
        }
        private Keeper keeper;
    }

    public static class SequentalReader implements Runnable {
        public SequentalReader(Keeper keeper) {
            this.keeper = keeper;
        }

        public void run() {
            try {
                for (int i = 0, size = keeper.vector.size(); i < size; ++i) {
                    synchronized(keeper) {
                        while (keeper.isWrite) {
                            keeper.wait();
                        }
                        System.out.println("Read: " + keeper.vector.get(i) + " from position " + i);
                        keeper.isWrite = true;
                        keeper.notify();
                    }
                }
            } catch (Exception e) {
                System.out.println(e.toString());
            }
        }
        private Keeper keeper;
    }
}

預期行為(現在似乎可行,但我不確定它會一直如此。):

[Test] arr1: 0.0 0.0
Write: 0.11832270210075957 to position 0
Read: 0.11832270210075957 from position 0
Write: 0.18019604451043925 to position 1
Read: 0.18019604451043925 from position 1
[Test] arr2: 0.0 0.0 0.0
Write: 0.9208224707735939 to position 0
Read: 0.9208224707735939 from position 0
Write: 0.5204299894796229 to position 1
Read: 0.5204299894796229 from position 1
Write: 0.6221915557485913 to position 2
Read: 0.6221915557485913 from position 2
[Test] list: 0.0 0.0 0.0 0.0
Write: 0.2718292615666258 to position 0
Read: 0.2718292615666258 from position 0
Write: 0.5589338156490498 to position 1
Read: 0.5589338156490498 from position 1
Write: 0.11919746734454817 to position 2
Read: 0.11919746734454817 from position 2
Write: 0.7266106446478366 to position 3
Read: 0.7266106446478366 from position 3

經典的方法是使用信號量:

import java.lang.Thread;
import java.util.concurrent.Semaphore;

public class Task7Part2 {

public static void main(String[] args) throws InterruptedException {
    IVector arr1 = new IVector(2);
    System.out.print("[Test] arr1: "); arr1.print();
    Keeper keeperArr1 = new Keeper(arr1);
    SequentalWriter seqWriter = new SequentalWriter(keeperArr1);
    SequentalReader seqReader = new SequentalReader(keeperArr1);
    Thread thread1 = new Thread(seqWriter);
    thread1.start();
    Thread thread2 = new Thread(seqReader);
    thread2.start();
    thread1.join();
    thread2.join();
}

public static class Keeper {
    public IVector vector;
    public Semaphore allowWrite=new Semaphore(1);
    public Semaphore allowRead=new Semaphore(0);

    public Keeper(IVector vector) {
        this.vector = vector;
    }

    public Double get(int i) throws InterruptedException {
        allowRead.acquire();
        Double res = vector.get(i);
        allowWrite.release();
        return res;
    }

    public void set(int i, double d) throws InterruptedException {
        allowWrite.acquire();
        vector.set(i,d);
        allowRead.release();
    }
}

public static class SequentalWriter implements Runnable {
    private Keeper keeper;

    public SequentalWriter(Keeper keeper) {
        this.keeper = keeper;
    }

    public void run() {
        try {
            for (int i = 0, size = keeper.vector.size(); i < size; ++i) {
                double d = Math.random();
                keeper.set(i, d);
                System.out.println("Write: " + d + " to position " + i);
            }
        } catch (Exception e) {
            System.out.println(e.toString());
        }
    }
}

public static class SequentalReader implements Runnable {
    private Keeper keeper;

    public SequentalReader(Keeper keeper) {
        this.keeper = keeper;
    }

    public void run() {
        try {
            for (int i = 0, size = keeper.vector.size(); i < size; ++i) {
                System.out.println("Read: " + keeper.get(i) + " from position " + i);
            }
        } catch (Exception e) {
            System.out.println(e.toString());
        }
    }
}
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM