Reputation: 48
The topic was continued here: https://codereview.stackexchange.com/q/249978/231182
I am new to the Java programming language.
Task: Create SequentalWriter and SequentalReader classes that implement the Runnable interface. They must provide a sequence of write-read operations (i.e., write-read-write-read-write-read, etc.).
I would like to know if this implementation is correct or something needs to be changed?
Besides, minor bugs and errors are also welcome.
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;
}
}
Expected behavior (What seems to work right now, but I'm not sure it will always be that way.):
[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
Upvotes: 1
Views: 131
Reputation: 13535
the classic approach is to use Semaphores:
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());
}
}
}
}
Upvotes: 1