I'm trying to simulate a can fruit factory. As the cans are sterilised 4 at a time, the filling takes place. Only the cans that are sterilised can be filled. How do I implement this? Because as for my output, it says that it sterilizes can 1,2,3,4, which means that the next stage, it it supposed to fill can 1, but instead, it fills can 5
public static void main(String[] args) throws
ExecutionException {
LinkedBlockingQueue<can> belt = new
LinkedBlockingQueue();
LinkedBlockingQueue<can> steril = new
LinkedBlockingQueue(4);
LinkedBlockingQueue<can> fill = new
LinkedBlockingQueue();
ExecutorService factory =
Executors.newCachedThreadPool();
for (int i = 1; i <= 100; i++) {
can c = new can(i);
System.out.println("---------------------------------------");
System.out.println("Can" + c.canNo + " entered factory");
//filling f = new filling(c, steril, fill);
try {
Future<can> dentscan = factory.submit(new dentscanner(c, belt, steril, fill));
Thread.sleep(500);
//factory.submit(f);
} catch (InterruptedException e) {
}
}
}
}
class can {
int canNo;
boolean sterilized = false;
public can(int canNo) {
this.canNo = canNo;
}
}
public dentscanner(can c, LinkedBlockingQueue<can> belt, LinkedBlockingQueue<can> steril, LinkedBlockingQueue fill) {
this.c = c;
this.belt = belt;
this.steril = steril;
this.fill = fill;
}
#Override
public can call() throws Exception {
ExecutorService factory =
Executors.newCachedThreadPool();
sterilisation s = new sterilisation(c, belt, steril, fill);
int dent = rand.nextInt(10);
System.out.println("\tScanning for Can" + c.canNo
+ " for Dents");
if (dent == 3) {
System.out.println("\t\tStatus: Dented");
System.out.println("\t\t\tCan" + c.canNo + "
Rejected");
System.out.println("\t\t\tRemoved from belt");
return null;
} else {
System.out.println("\t\tStatus:No Dents");
System.out.println("\tPassing Can " + c.canNo +
" for sterilisation");
belt.put(c);
factory.submit(s);
Thread.sleep(1000);
return c;
}
}
}
class sterilisation implements Runnable {
can c;
LinkedBlockingQueue<can> belt;
LinkedBlockingQueue<can> steril;
LinkedBlockingQueue<can> fill;
int counter = 0;
public sterilisation(can c, LinkedBlockingQueue<can> belt, LinkedBlockingQueue<can> steril, LinkedBlockingQueue fill) {
this.c = c;
this.belt = belt;
this.steril = steril;
this.fill = fill;
}
#Override
public void run() {
ExecutorService factory = Executors.newCachedThreadPool();
filling f = new filling(c, steril, fill);
try {
can c = belt.take();
steril.put(c);
if (steril.size() == 4) {
for (int i = 1; i < 5; i++) {
try {
System.out.println("Can" + steril.take().canNo + " sterilised");
} catch (InterruptedException ex) {
}
}
c.sterilized = true;
}
if (c.sterilized) {
factory.submit(f);
counter = 0;
}
} catch (InterruptedException ex) {
}
}
}
class filling implements Runnable {
can c;
LinkedBlockingQueue<can> steril;
LinkedBlockingQueue<can> fill;
public filling(can c, LinkedBlockingQueue<can> steril, LinkedBlockingQueue<can> fill) {
this.c = c;
this.steril = steril;
this.fill = fill;
}
#Override
public void run() {
ExecutorService factory = Executors.newCachedThreadPool();
try {
fill.put(steril.take());
System.out.println("Filling Can" + fill.take().canNo);
} catch (InterruptedException ex) {
}
}
}
Here is the output
Passing Can 4 for sterilisation
Can1 sterilised
Can2 sterilised
Can3 sterilised
Can4 sterilised
---------------------------------------
Can5 entered factory
Scanning for Can5 for Dents
Status:No Dents
Passing Can 5 for sterilisation
Filling Can5
Not a complete answer, but a few hints. Model the processes as threads. Sterilization is one thread, processing 4 cans at a time. Filling is another thread, processing one can at a time. Connect the processes (threads) with input and output queues (BlockingQueues):
---Q1--> Sterilization ---Q2--> Filling ---Q3--> ?
After thinking and some experimentation you will find that every "process" has (at least) four properties in common. I'll give you the first two: Input queue and Output queue. The remaining two I leave as an exercise.
Related
Right now I write a Java program that has as purpose detect deadlocks and recovery from this situation. The program input is two numbers, N = Number of types of resources and M = Number of process.
I wanted to do something like this:
private static void test2() {
final ReentrantLock lock1 = new ReentrantLock();
final ReentrantLock lock2 = new ReentrantLock();
Thread thread1 = new Thread(new Runnable() {
#Override public void run() {
try {
lock1.lock();
System.out.println("Thread1 acquired lock1");
try {
TimeUnit.MILLISECONDS.sleep(50);
} catch (InterruptedException ignore) {}
lock2.lock();
System.out.println("Thread1 acquired lock2");
}
finally {
lock2.unlock();
lock1.unlock();
}
}
});
thread1.start();
Thread thread2 = new Thread(new Runnable() {
#Override public void run() {
try {
lock2.lock();
System.out.println("Thread2 acquired lock2");
try {
TimeUnit.MILLISECONDS.sleep(50);
} catch (InterruptedException ignore) {}
lock1.lock();
System.out.println("Thread2 acquired lock1");
}
finally {
lock1.unlock();
lock2.unlock();
}
}
});
thread2.start();
// Wait a little for threads to deadlock.
try {
TimeUnit.MILLISECONDS.sleep(100);
} catch (InterruptedException ignore) {}
detectDeadlock();
}
But instead of 2, N locks and I have several problems for doing this. Here my code with my attempt:
class Main {
private static int MAX_AVAILABLE = 10;
private static int IDLE = 1000;
public static void main(String[] args) throws java.lang.Exception{
int n, m; //number of resources and process, respectively
ReentrantLock[] resources; // Locks for resources
int[] available; // Number of instances per resource
Process[] processes; // Processes array
DeadlockDetector supervisor; // Deadlock detaction class
n = Integer.valueOf(args[0]);
m = Integer.valueOf(args[1]);
resources = new ReentrantLock[n];
available = new int[n];
processes = new Process[m];
supervisor = new DeadlockDetector();
// Create resources array
for(int i=0; i<n; ++i){
available[i] = (int)(Math.floor(Math.random()*MAX_AVAILABLE + 1));
resources[i] = new ReentrantLock();
System.out.println("R"+String.valueOf(i+1)+"-> instances: "+String.valueOf(available[i]));
}
// Creating processes
for(int i=0; i<m; ++i){
processes[i] = new Process(i, resources, available, n);
System.out.println("P"+String.valueOf(i+1)+"-> requested "+Arrays.toString(processes[i].requested));
processes[i].start();
}
//Run deadlock detection
try {
TimeUnit.MILLISECONDS.sleep(IDLE);
}catch (InterruptedException ignore){}
supervisor.start();
}
}
class Process extends Thread{
public int id;
public int total; // Total of resources instances needed for finished the process
public ReentrantLock[] resources;
public int[] requested; // Number of instances needed per resource type
public boolean[] needed; // Boolean indicating whether the process needs at least one instance of the resource i
public int n;
private static int MIN_TIME = 1000;
private static int MAX_TIME = 3000;
public Process(int index, ReentrantLock[] res, int[] available, int n_resources){
id = index;
n = n_resources;
resources = res;
total = 0;
requested = new int[n];
needed = new boolean[n];
for(int i=0; i<n; ++i){
requested[i] = (int)(Math.floor(Math.random()*available[i]));
needed[i] = requested[i] > 0;
total += requested[i];
}
}
#Override
public void run(){
int resourceT = 0;
int timeToSleep;
System.out.println("P"+String.valueOf(id+1)+" begin running");
try{
while(total > 0){
resourceT = (int)(Math.floor(Math.random()*n));
if(requested[resourceT] < 1){
System.out.println("P"+String.valueOf(id+1)+"-> I do not need more R"+String.valueOf(resourceT+1));
continue;
}
System.out.println("P"+String.valueOf(id+1)+"-> I'll take R"+String.valueOf(resourceT+1));
resources[resourceT].lock();
timeToSleep = (int)(Math.floor(Math.random()*(MAX_TIME - MIN_TIME)) + MIN_TIME);
try{
TimeUnit.MILLISECONDS.sleep(timeToSleep);
}catch (InterruptedException ignore){}
--total;
--requested[resourceT];
}
}finally{
for(int i=0; i<n; ++i){
if(needed[i] && resources[i].isHeldByCurrentThread())
resources[i].unlock();
}
}
System.out.println("P"+String.valueOf(id+1)+"-> Im finished");
}
}
class DeadlockDetector extends Thread{
public ThreadMXBean threadBean;
public long[] threadIds;
public DeadlockDetector(){
}
#Override
public void run(){
Boolean good;
this.threadBean = ManagementFactory.getThreadMXBean();
threadIds = threadBean.findDeadlockedThreads();
int deadlockedThreads = threadIds != null? threadIds.length : 0;
if(deadlockedThreads>1){
good = false;
System.out.println("Number of deadlocked threads: " + deadlockedThreads);
//recoverDeadlock();
//break;
}
}
public void recoverDeadlock(){
}
}
Please, could anyone help me fix this detail? Thanks!
There is a task: to make a multi-threaded execution of functions using AsynchronousSocketChannel. To simulate long work on the server side i'm using Thread.sleep() (stored in the class Worker). If I sleep() threads for more than 2 seconds, when obtaining data on the client side using ByteBuffer and Future, flies java.lang.IndexOutOfBoundsException (my function printFuncResult) Tell me, please, what's the problem?
Server:
public class Server {
public static final InetSocketAddress hostAddress = new InetSocketAddress("localhost", 5678);
private AsynchronousServerSocketChannel serverChannel;
private AsynchronousSocketChannel clientChannel;
ExecutorService threadPool;
public Server() throws IOException, ExecutionException, InterruptedException {
serverChannel = AsynchronousServerSocketChannel.open();
serverChannel.bind(hostAddress);
System.out.println("Server channel bound to port: " + hostAddress.getPort());
System.out.println("Waiting for client to connect... ");
getClientChannel();
handleArguments();
}
private void getClientChannel() throws ExecutionException, InterruptedException {
Future<AsynchronousSocketChannel> acceptResult = serverChannel.accept();
clientChannel = acceptResult.get();
}
private void handleArguments() throws IOException, InterruptedException {
if ((clientChannel != null) && (clientChannel.isOpen())) {
ByteBuffer buffer = ByteBuffer.allocate(32);
Future<Integer> result = clientChannel.read(buffer);
while (! result.isDone()) {
// System.out.println("Result coming... ");
}
buffer.flip();
int x = buffer.getInt(0);
Worker workerOne = new Worker(Worker.TYPE_F, x, clientChannel);
Worker workerTwo = new Worker(Worker.TYPE_G, x, clientChannel);
threadPool = Executors.newFixedThreadPool(2);
threadPool.execute(workerOne);
threadPool.execute(workerTwo);
Thread.sleep(3000);
clientChannel.close();
}
}
}
class Worker implements Runnable {
public static final int TYPE_F = 1;
public static final int TYPE_G = 2;
private int x;
private int type;
private AsynchronousSocketChannel clientChannel;
public Worker(int type, int x, AsynchronousSocketChannel clientChannel) {
this.x = x;
this.type = type;
this.clientChannel = clientChannel;
}
private void sendResultToClient(int res) {
ByteBuffer buffer = ByteBuffer.allocate(32);
if (type == TYPE_F) {
res = 4545;
} else {
res = 34234;
}
buffer.putInt(0, type);
buffer.putInt(4, res);
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
for (int i = 0; i < 10000; ++i) {
for (int j = 0; j < 10000; ++j) {
int k = i*j + i/(j +1) + i + j + Math.max(i, j);
}
}
boolean written = false;
while (!written) {
try {
clientChannel.write(buffer);
written = true;
} catch (Exception e) {}
}
}
#Override
public void run() {
int result = -1;
Random random = new Random();
switch (type) {
case TYPE_F :
result = (int)Math.pow(x, x);
break;
case TYPE_G :
result = (int)Math.pow(x, x / 2);
break;
}
sendResultToClient(result);
}
}
Client:
public class Client {
private AsynchronousSocketChannel clientChannel;
ExecutorService threadPool;
public Client(int x) throws IOException, InterruptedException, ExecutionException {
threadPool = Executors.newFixedThreadPool(2);
boolean connected = false;
while (!connected) {
try {
clientChannel = AsynchronousSocketChannel.open();
Future<Void> future = clientChannel.connect(Server.hostAddress);
future.get();
connected = true;
} catch (ExecutionException e) {}
}
System.out.println("Client is started: " + clientChannel.isOpen());
System.out.println("Sending messages to server: ");
sendArguments(x);
//showCancelDialog();
listenResult();
clientChannel.close();
}
private void sendArguments(int x) throws InterruptedException, IOException {
ByteBuffer buffer = ByteBuffer.allocate(32);
buffer.putInt(0, x);
Future<Integer> result = clientChannel.write(buffer);
while (! result.isDone()) {
System.out.println("... ");
}
}
private boolean waitForResult(Future <Pair <Integer, Integer>> futureResult) {
Scanner sc = new Scanner(System.in);
while (!futureResult.isDone() ) {
System.out.println("DOING.. break? (y/n)");
String input = sc.next();
if (input.equals("y")) {
System.out.println("CANCELLED");
threadPool.shutdownNow();
return false;
}
}
return true;
}
private void printFuncResult(Future <Pair <Integer, Integer>> futureResult) throws ExecutionException, InterruptedException {
Integer funcType = new Integer(futureResult.get().getKey());
Integer result = new Integer(futureResult.get().getValue());
System.out.println("RESULT OF "+ funcType +" FUNC = " + result);
}
private void listenResult() throws ExecutionException, InterruptedException {
System.out.println("Wating for result...");
Listener listener = new Listener(clientChannel);
Future <Pair <Integer, Integer>> futureResult = threadPool.submit(listener);
if (!waitForResult(futureResult)) {
return;
}
printFuncResult(futureResult);
futureResult = threadPool.submit(listener);
if (!waitForResult(futureResult)) {
return;
}
printFuncResult(futureResult);
}
}
class Listener implements Callable <Pair <Integer, Integer>> {
private AsynchronousSocketChannel clientChannel;
public Listener(AsynchronousSocketChannel channel) {
this.clientChannel = channel;
}
#Override
public Pair <Integer, Integer> call() throws Exception {
ByteBuffer buffer = ByteBuffer.allocate(32);
Future<Integer> futureResult = clientChannel.read(buffer);
while (! futureResult.isDone()) {}
buffer.flip();
Integer type = new Integer(buffer.getInt(0));
Integer result = new Integer (buffer.getInt(4));
return new Pair<Integer, Integer>(type, result);
}
}
}
The IndexOutOfBoundsException is not coming from printFuncResult. It is only stored in the future and printed with the stack trace there. The IndexOutOfBoundsException is generated in Listener call function on this line:
Integer type = new Integer(buffer.getInt(0));
This will happen if the read did not read a sufficient number of bytes.
I suggest you replace this inefficient and hard to debug while loop .
while (! futureResult.isDone()) {}
with something like
int bytes_read = futureResult.get();
if(bytes_read != 32) {
// log error or throw exception or retry ...
}
I've recently been learning about semaphores to specify the ordering of threads, but I'm curious about how to control the frequency as well. Below is a program that prints *, a digit, and then a letter to the screen. Always in that order (e.g. *1A). How can I make it so certain threads print more than once before the others? (e.g. *32A)
import java.lang.Thread;
import java.util.concurrent.*;
public class ThreadSync {
private static boolean runFlag = true;
private static Semaphore canPrintSymbol = new Semaphore(1);
private static Semaphore canPrintDigit = new Semaphore(0);
private static Semaphore canPrintLetter = new Semaphore(0);
public static void main( String[] args ) {
Runnable[] tasks = new Runnable[17];
Thread[] threads = new Thread[17];
// Create 10-digit threads
for (int d = 0; d < 10; d++) {
tasks[d] = new PrintDigit((char)('0' + d));
threads[d] = new Thread(tasks[d]);
threads[d].start();
}
// Create 6-letter threads
for (int d = 0; d < 6; d++) {
tasks[d + 10] = new PrintLetter((char)('A' + d));
threads[d + 10] = new Thread(tasks[d + 10]);
threads[d + 10].start();
}
// Create a thread to print asterisk
tasks[16] = new PrintSymbol('*');
threads[16] = new Thread(tasks[16]);
threads[16].start();
// Let the threads run for a period of time
try { Thread.sleep(500); }
catch (InterruptedException ex) { ex.printStackTrace(); }
runFlag = false;
// Interrupt the threads
for (int i = 0; i < 17; i++) threads[i].interrupt();
}
public static class PrintSymbol implements Runnable {
private char c;
public PrintSymbol(char c) {
this.c = c;
}
public void run() {
while (runFlag) {
try {
canPrintSymbol.acquire();
}
catch (InterruptedException ex) {
ex.printStackTrace();
}
System.out.printf("%c\n", c);
canPrintDigit.release();
}
}
}
public static class PrintDigit implements Runnable {
private char c;
public PrintDigit(char c) { this.c=c; }
public void run() {
while (runFlag) {
try {
canPrintDigit.acquire();
}
catch (InterruptedException ex) {
ex.printStackTrace();
}
System.out.printf("%c\n", c);
canPrintLetter.release();
}
}
}
public static class PrintLetter implements Runnable {
private char c;
public PrintLetter(char c) {
this.c = c;
}
public void run() {
while (runFlag) {
try {
canPrintLetter.acquire();
}
catch (InterruptedException ex) {
ex.printStackTrace();
}
System.out.printf("%c\n", c);
canPrintSymbol.release();
}
}
}
}
Short answer is you can't. At least not to my knowledge. There are hints you can give to the OS like yielding your thread. This means it yields it processing to the next thread. Other then that all you can really do is influence the priority. But all these are just hints to the OS. The OS ultimately determines the order in which the threads are executed. This is one of the main things to keep in mind when working with multiple threads. It is generally not a good idea to have a dependency between separate threads which makes the order of execution important.
I have an issue setting up a critical section with a semaphore between 2 threads. I am using a semaphore to acquire(send) in my Customer thread and release in my teller thread. However when I run my program it is always hanging and I don't know why. I have tried several things and i am not sure what the issue was.
I am trying to use the deposit semaphore to set up a critical section with the customer thread and teller thread.
import java.util.concurrent.Semaphore;
public class Threads {
// private int customerNumber = 0;
private static Semaphore deposit = new Semaphore (0, true);
public static void main(String[] args)
{
final int customerThreads = 5;
final int tellerThreads = 2;
final int loanThreads = 1;
Customer thr[] = new Customer[customerThreads]; // make 5 customer threads
Thread cThread[] = new Thread[customerThreads]; // made 5 threads
for (int i= 0; i < customerThreads; i++)
{
thr[i]= new Customer(i);
cThread[i] = new Thread(thr [i]);
cThread[i].start();
}
for ( int i = 0; i < customerThreads; i++ )
{
try {
cThread[i].join ();
System.out.println("Customer"+i + "joined from main");
}
catch (InterruptedException e)
{
}
}
Teller thr1[] = new Teller[tellerThreads];
Thread tThread[] = new Thread[tellerThreads];
for (int b = 0; b< tellerThreads; b++)
{
thr1[b] = new Teller(b);
tThread[b]= new Thread(thr1 [b]);
tThread[b].start();
}
LoanOfficer thr2[] = new LoanOfficer[loanThreads];
Thread lThread[] = new Thread[loanThreads];
for(int c = 0; c< loanThreads; c++)
{
thr2[c] = new LoanOfficer(c);
lThread[c] = new Thread(thr2 [c]);
lThread[c].start();
}
// TODO code application logic here
}
static class Customer implements Runnable
{
private int customerNumber = 0;
private int balance = 0;
Customer(int cn)
{
this.customerNumber = cn;
balance = 1000;
System.out.println("Customer"+ customerNumber + "created");
}
public void run()
{
try
{
Thread.sleep(200);
deposit.acquire();
}
catch(InterruptedException e)
{
Thread.currentThread().interrupt();
e.printStackTrace();
}
//System.out.println("Customer"+ customerNumber + "created");
// try
}
public void post()
{
}
}
static class Teller implements Runnable
{
private int tellerNumber = 0;
Teller(int tn)
{
this.tellerNumber = tn;
System.out.println("Teller"+ tellerNumber +"created");
}
public void run()
{
deposit.release();
// try
// {
//
// // deposit.release();
//
// Thread.sleep(100);
// // deposit.acquire();
// }
// catch(InterruptedException e)
// {
// deposit.release();
// }
//System.out.println("Teller"+ tellerNumber +"created");
}
public void post()
{
}
}
static class LoanOfficer implements Runnable
{
private int loanNumber = 0;
LoanOfficer(int tn)
{
this.loanNumber = tn;
System.out.println("LoanOfficer"+loanNumber+"created");
}
public void run()
{
//System.out.println("LoanOfficer"+loanNumber+"created");
}
public void post()
{
}
}
}
You instantiate semaphore with no permits as below:
private static Semaphore deposit = new Semaphore (0, true);
Hence when you try to call acquire, you wont get the permit to execute beyond and hence blocks. So try atleast having 1 permit so at a time only 1 thread can execute post you acquire the permit from semaphore. You could increase that later as well.
private static Semaphore deposit = new Semaphore (1, true);
Refer the doc here
I am trying to spawn off a handful of threads and place them in a List as they execute. As they complete their processing I would like to collect their results for presentation. That way I can have a list containing many threads and then once they become available I can call future.get and use their callback information.
For some reason, I am missing many of the results. When I step through the code, f.get() is being passed over when it shouldn't be and I cannot figure out why.
My code is as follows:
public class ThreadTesterRunner {
static List<Integer> randoms = new ArrayList<>();
public static void main(String[] args) throws InterruptedException {
final Phaser cb = new Phaser();
ThreadRunner tr = new ThreadRunner(cb);
Thread t = new Thread(tr, "Thread Runner");
t.start();
boolean process = true;
// wait until all threads process, then print reports
while (process){
if(tr.isFinished()){
System.out.println("Print metrics");
process = false;
}
Thread.sleep(1000);
}
}
}
class ThreadRunner implements Runnable {
private ExecutorService executorService = Executors.newFixedThreadPool(10);
private final Phaser barrier;
private boolean finished=false;
public ThreadRunner(Phaser phaser) {this.barrier = phaser;}
public void run(){
try {
List<Future<Integer>> list = new ArrayList<>();
boolean stillLoop = true; int i = 0;
final Phaser p = this.barrier;
Callable<Integer> task = new Callable<Integer>() {
public Integer call() throws Exception {
return new Reader().doRun(p);
}
};
List<Integer> randoms = new ArrayList<>();
Integer size;
while (stillLoop){
System.out.println("i "+i);
list.add(executorService.submit(task));
for(Future<Integer> f: list){
if(f.isDone()){
size = f.get();
System.out.println("size "+size);
list.remove(f);
} else {
// keep processing
}
}
if(i == 2){
System.out.println("breaking out of loop");
stillLoop = false;
}
i++;
}
this.barrier.awaitAdvance(0);
this.finished=true;
} catch (Exception e1) {
e1.printStackTrace();
}
}
public boolean isFinished(){
return this.finished;
}
}
class Reader {
private Phaser readBarrier;
private ExecutorService executorService = Executors.newFixedThreadPool(20);
public Reader() {
}
Random randomGenerator = new Random();
public Integer doRun(Phaser phaser) throws Exception {
phaser.register();
this.readBarrier = phaser;
System.out.println("Reading...");
int i;
int r = randomGenerator.nextInt(100);
System.out.println("r "+r);
ThreadTesterRunner.randoms.add(r);
int a = this.readBarrier.arrive();
return r; //i;
}
}
Any idea's as to why this may be happening?
EDIT:
Alright, I think I have it up and running:
class ThreadRunner implements Runnable {
// static int timeOutTime = 2;
private ExecutorService executorService = Executors.newFixedThreadPool(10);
private final Phaser barrier;
private boolean finished = false;
public ThreadRunner(Phaser phaser) {
this.barrier = phaser;
}
public void run() {
try {
List<Future<Integer>> list = new CopyOnWriteArrayList<>();
boolean stillLoop = true;
int i = 0;
final Phaser p = this.barrier;
Callable<Integer> readerTask = new Callable<Integer>() {
public Integer call() throws Exception {
return new Reader().doRun(p);
}
};
List<Integer> randoms = new ArrayList<>();
Integer size;
while (stillLoop) {
if (i <= 2) {
list.add(executorService.submit(readerTask));
}
if (!list.isEmpty()) {
for (Future<Integer> f : list) {
if (f.isDone()) {
size = f.get();
randoms.add(size);
System.out.println("Process read with a size of "+ size);
list.remove(f);
} else {
// System.out.println("skipping");
}
}
} else {
stillLoop = false;
}
i++;
}
System.out.println("at barrier waiting");
this.barrier.awaitAdvance(0);
System.out.println("barrier crossed");
this.finished = true;
} catch (Exception e1) {
e1.printStackTrace();
}
}
public boolean isFinished() {
return this.finished;
}
}
Results:
i 0
i 1
i 2
breaking out of loop
Reading...
Reading...
r 13
r 44
Reading...
r 78
Print metrics
I changed the ArrayList to a Vector since ArrayList is not thread safe which would eventually cause a ConcurrentModificationException.
Is the above output what you would expect?