I have a multithreaded quicksort algorithm witch runs correct but then never stops executing.
I tried adding return statemants everywhere but nothing helps.
How do I stop all thread from running when they are done? Is there a way for a thread terminate its self when done?
public class Parallel {
private static final int numberOfThreads = Runtime.getRuntime().availableProcessors();
private static final int fallback = 2;
private static Executor pool = Executors.newFixedThreadPool(numberOfThreads);
//public static int[] numberArray;
public static <T extends Comparable<T>> void sort(int[] numberArray){
if(numberArray == null || numberArray.length == 0){
return;
}
final AtomicInteger count = new AtomicInteger(1);
pool.execute(new QuicksortRunnable<T>(numberArray, 0, numberArray.length-1, count));
try {
synchronized (count) {
count.wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private static class QuicksortRunnable<T extends Comparable<T>> implements Runnable {
private final int[] values;
private final int left;
private final int right;
private final AtomicInteger count;
public QuicksortRunnable(int[] values, int left, int right, AtomicInteger count) {
this.values = values;
this.left = left;
this.right = right;
this.count = count;
}
#Override
public void run() {
quicksort(left, right);
synchronized (count) {
// AtomicInteger.getAndDecrement() returns the old value. If the old value is 1, then we know that the actual value is 0.
if (count.getAndDecrement() == 1)
count.notify();
}
return;
}
private void quicksort(int pLeft, int pRight) {
int pivotIndex = (pRight - pLeft) / 2 + pLeft;
int pivot = values[pivotIndex];
int j = pRight;
int i = pLeft;
while (i < j) {
while (values[i] > pivot) {
i++;
}
while (values[j] < pivot) {
j--;
}
if (i <= j) {
int temp = values[i];
values[i] = values[j];
values[j] = temp;
i++;
j--;
}
}
if (count.get() >= fallback * numberOfThreads) {
if (pLeft < j){
quicksort(pLeft, j);
}
if (i < pRight) {
quicksort(i, pRight);
}
} else {
if (pLeft < j) {
count.getAndAdd(1);
pool.execute(new QuicksortRunnable<T>(values, pLeft, j, count));
}
if (i < pRight) {
count.getAndAdd(1);
pool.execute(new QuicksortRunnable<T>(values, i, pRight, count));
}
}
}
}
And my Main function
public static void main(String args[]) {
Random rand = new Random();
int length = 100000;
int[] parallelArray = new int[length];
for (int i = 0; i < length; i++) {
int temp = rand.nextInt(length);
parallelArray[i] = temp;
}
sort(parallelArray);
boolean t = check(parallelArray);
System.out.println(t);
}
Function to test if code is sorted.
public static boolean check(int[] A) {
for (int i = 0; i < A.length - 1; i++) {
// System.out.print(" " + A[i]);
if (A[i] < A[i + 1]) {
return false;
}
}
return true;
}
When you use a ExecutorService you need to call the ExecutorService.shutdown() after all tasks are submitted, then you need to wait for the pool to shut down by calling ExecutorService.awaitTermination() and supply the time to wait as parameters. This is because the pool is comprised of non-daemon threads and the jvm does not exit if there are non-daemon threads still running.
So change the this to use the ExecutorService from Executor to enable hooks:
private static ExecutorService pool = Executors.newFixedThreadPool(numberOfThreads);
Then call shutdown() in the finally block:
public static <T extends Comparable<T>> void sort(int[] numberArray) {
if (numberArray == null || numberArray.length == 0) {
return;
}
final AtomicInteger count = new AtomicInteger(1);
pool.execute(new QuicksortRunnable<T>(numberArray, 0, numberArray.length - 1, count));
try {
synchronized (count) {
count.wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
pool.shutdown(); //call shutdown() here
try {
pool.awaitTermination(5, TimeUnit.MINUTES); //wait for 5 minutes
}catch (InterruptedException ie) {
ie.printStackTrace();
}
}
}
In the finally section call shutdown() to initiate a orderly shut down of the threads in the pool and as the shutdown call is not blocking the awaitTermination() has to be called for the calling thread to wait for the shut down process to finish.
Isn't 5 min to wait a bit too much?
The call to awaitTermination does not necessarily wait the full five minutes. The 5 minutes is the maximum time to wait, not the minimum. To quite the Javadoc:
Blocks until all tasks have completed execution after a shutdown request, or the timeout occurs, or the current thread is interrupted, whichever happens first.
Related
I found on a book this alternative solution for "Dining philosopher problem", in Java:
public class Philosopher extends Thread {
private final int maxPause = 100;
private int bites = 10;
private Chopstick lower;
private Chopstick higher;
private int index;
public Philosopher(int i, Chopstick left, Chopstick right) {
index = i;
if (left.getNumber() < right.getNumber()) {
this.lower = left;
this.higher = right;
} else {
this.lower = right;
this.higher = left;
}
}
public void eat() {
System.out.println("Philosopher " + index + ": start eating");
pickUp();
chew();
putDown();
System.out.println("Philosopher " + index + ": done eating");
}
public void pickUp() {
pause();
lower.pickUp();
pause();
higher.pickUp();
pause();
}
public void chew() {
System.out.println("Philosopher " + index + ": eating");
pause();
}
public void pause() {
try {
int pause = AssortedMethods.randomIntInRange(0, maxPause);
Thread.sleep(pause);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void putDown() {
higher.putDown();
lower.putDown();
}
public void run() {
for (int i = 0; i < bites; i++) {
eat();
}
}
}
public class Chopstick {
private Lock lock;
private int number;
public Chopstick(int n) {
lock = new ReentrantLock();
this.number = n;
}
public void pickUp() {
lock.lock();
}
public void putDown() {
lock.unlock();
}
public int getNumber() {
return number;
}
}
The text of the solution is:
Alternatively, we can label the chopsticks with a number from e to N - 1. Each philosopher attempts to pick up the lower numbered chopstick first. This essentially means that each philosopher goes for the left chopstick before right one (assuming that's the way you labeled it), except for the last philosopher who does this in reverse. With this solution, a philosopher can never hold the larger chopstick without holding the smaller one. This
prevents the ability to have a cycle, since a cycle means that a higher chopstick would "point"to a lower one.
But it's not clear for me. Someone can help me with an example?
Thanks
----EDIT-----
Main class:
public class Question {
public static int size = 3;
public static int leftOf(int i) {
return i;
}
public static int rightOf(int i) {
return (i + 1) % size;
}
public static void main(String[] args) {
Chopstick[] chopsticks = new Chopstick[size + 1];
for (int i = 0; i < size + 1; i++) {
chopsticks[i] = new Chopstick(i);
}
Philosopher[] philosophers = new Philosopher[size];
for (int i = 0; i < size; i++) {
Chopstick left = chopsticks[leftOf(i)];
Chopstick right = chopsticks[rightOf(i)];
philosophers[i] = new Philosopher(i, left, right);
}
for (int i = 0; i < size; i++) {
philosophers[i].start();
}
}
}
Let's have
3 philosophers - p1,p2,p3 and 3 chopsticks c1,c2,c3 (index of chopstick is equal to number)
you create then p1(c1, c2), p2(c2, c3), p3(c1, c3)
worst case scenario:
p1 acquires lock on c1
meanwhile p2 acquires lock on c2 -> blocks p1
p3 is blocked by p1(still holding c1 lock) -> p2 is free to acquire c3
p2 acquires c3 -> finishes and releases c2 and c3
p1 acquires c2 -> finishes and releases c1 and c2
p3 acquires c1 and c3 -> finishes and releases c1 and c3
I know it means the reference to the array is volatile not the items in the array if you declare an array volatile.
I am learning mutex algorithm, so I write some test code:
public class MutualExclusion {
static final int N = 10;
static final int M = 100000;
volatile static int count = 0;
public static void main(String[] args) {
Thread[] threads = new Thread[N];
for (int i = 0; i < N; i++) {
Thread t = new Worker(i);
threads[i] = t;
t.start();
}
for (Thread t: threads) {
try {
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if (count != N * M) {
System.out.println("count (" + count + ") != N * M (" + String.valueOf(N * M) + ")");
}
}
static class Worker extends Thread {
int id;
Worker(int id) {
this.id = id;
}
#Override
public void run() {
for (int i = 0; i < M; i++) {
this.lock();
// critical section
count++;
if (i % 1000 == 0) {
System.out.println(this.getName() + ": " + count);
}
this.unlock();
}
}
void lock() {
filterLock();
}
void unlock() {
filterUnlock();
}
static volatile int level[] = new int[N];
static volatile int lastToEnter[] = new int[N - 1];
void filterLock() {
for (int i = 0; i < (N - 1); i++) {
level[this.id] = i;
lastToEnter[i] = this.id;
outer:
while (lastToEnter[i] == this.id) {
for (int k = 0; k < N; k++ ) {
if (k != this.id && level[k] >= i) {
continue outer;
}
}
break;
}
}
}
void filterUnlock() {
level[this.id] = -1;
}
}
}
In my first implementation of filter algorithm, I missed volatile for variable level and lastToEnter, not surprisingly, the program went into a infinite loop. After I added the missing volatile, the program can end as expected.
As I said in beginning, a volatile array doesn't mean items in the array are volatile, so why can the program end as expected after I added the missing volatile?
I asked myself this question when I was implementing another mutex algorithm which still doesn't run correctly after I added volatile keyword. I have to use a trick (Java volatile array?) to make items in the array looks like being volatile: (code below can be pasted into Worker class directly)
volatile static boolean[] b = new boolean[N];
volatile static boolean[] c = new boolean[N];
volatile static int k = 0;
void dijkstraLock() {
b[this.id] = false;
outer:
for (;;) {
if (k == this.id) {
c[this.id] = false;
c = c; // IMPORTANT! the trick
for (int i = 0; i < N; i++) {
if (i != this.id && !c[i]) {
continue outer;
}
}
break;
} else {
c[this.id] = true;
if (b[k]) {
k = this.id;
}
}
}
}
void dijkstraUnlock() {
b[this.id] = true;
c[this.id] = true;
}
Volatile arrays in Java do not contain volatile elements - but if you access them via the array reference (which is volatile) you will get a volatile read. For instance, in the code above:
static volatile int lastToEnter[] = new int[N - 1];
is a volatile write, whereas
lastToEnter[i] = this.id;
is not. however, the evaluating of the array value - such as:
lastToEnter[i] == this.id
is a volatile read - you first read the reference to the array which is volatile, and only then access the i'th element to evaluate its value.
I suspect this is the reason your execution succeeds once the array is declared as volatile.
I'm developing a circular buffer with two Threads: Consumer and Producer.
I'm using active waiting with Thread.yield.
I know that it is possible to do that with semaphores, but I wanted the buffer without semaphores.
Both have a shared variable: bufferCircular.
While the buffer is not full of useful information, producer write data in the position pof array, and while there are some useful information consumer read data in the position c of array. The variable nElem from BufferCircular is the number of value datas that haven't been read yet.
The program works quite good 9/10 times that runs. Then, sometimes, it get stucks in a infinite loop before show the last element on screen (number 500 of loop for), or just dont' show any element.
I think is probably a liveLock, but I can't find the mistake.
Shared Variable:
public class BufferCircular {
volatile int[] array;
volatile int p;
volatile int c;
volatile int nElem;
public BufferCircular(int[] array) {
this.array = array;
this.p = 0;
this.c = 0;
this.nElem = 0;
}
public void writeData (int data) {
this.array[p] = data;
this.p = (p + 1) % array.length;
this.nElem++;
}
public int readData() {
int data = array[c];
this.c = (c + 1) % array.length;
this.nElem--;
return data;
}
}
Producer Thread:
public class Producer extends Thread {
BufferCircular buffer;
int bufferTam;
int contData;
public Productor(BufferCircular buff) {
this.buffer = buff;
this.bufferTam = buffer.array.length;
this.contData = 0;
}
public void produceData() {
this.contData++;
this.buffer.writeData(contData);
}
public void run() {
for (int i = 0; i < 500; i++) {
while (this.buffer.nElem == this.bufferTam) {
Thread.yield();
}
this.produceData();
}
}
}
Consumer Thread:
public class Consumer extends Thread {
BufferCircular buffer;
int cont;
public Consumer(BufferCircular buff) {
this.buffer = buff;
this.cont = 0;
}
public void consumeData() {
int data = buffer.readData();
cont++;
System.out.println("data " + cont + ": " + data);
}
public void run() {
for (int i = 0; i < 500; i++) {
while (this.buffer.nElem == 0) {
Thread.yield();
}
this.consumeData();
}
}
}
Main:
public class Main {
public static void main(String[] args) {
Random ran = new Random();
int tamArray = ran.nextInt(21) + 1;
int[] array = new int[tamArray];
BufferCircular buffer = new BufferCircular(array);
Producer producer = new Producer (buffer);
Consumer consumer = new Consumer (buffer);
producer.start();
consumer.start();
try {
producer.join();
consumer.join();
} catch (InterruptedException e) {
System.err.println("Error with Threads");
e.printStackTrace();
}
}
}
Any help will be welcome.
Your problem here is that your BufferCircular methods are sensitive to race conditions. Take for example writeData(). It executes in 3 steps, some of which are also not atomic:
this.array[p] = data; // 1
this.p = (p + 1) % array.length; // 2 not atomic
this.nElem++; // 3 not atomic
Suppose that 2 threads entered writeData() at the same time. At step 1, they both have the same p value, and both rewrite array[p] value. Now, array[p] is rewritten twice and data that first thread had to write, is lost, because second thread wrote to the same index after. Then they execute step 2--and result is unpredictable since p can be incremented by 1 or 2 (p = (p + 1) % array.length consists of 3 operations, where threads can interact). Then, step 3. ++ operator is also not atomic: it uses 2 operations behind the scenes. So nElem becomes also incremented by 1 or 2.
So we have fully unpredictable result. Which leads to poor execution of your program.
The simplest solution is to make readData() and writeData() methods serialized. For this, declare them synchronized:
public synchronized void writeData (int data) { //...
public synchronized void readData () { //...
If you have only one producer and one consumer threads, race conditions may occur on operations involving nElem. Solution is to use AtomicInteger instead of int:
final AtomicInteger nElem = new AtomicInteger();
and use its incrementAndGet() and decrementAndGet() methods.
I want to run some comparison of different approaches for concurrency technique.
But it throws next exceptions:
Warmup
BaseLine : 21246915
============================
Cycles : 50000
Exception in thread "pool-1-thread-3" Exception in thread "pool-1-thread-5" java.lang.ArrayIndexOutOfBoundsException: 100000
at concurrency.BaseLine.accumulate(SynchronizationComparisons.java:89)
at concurrency.Accumulator$Modifier.run(SynchronizationComparisons.java:39)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:744)
java.lang.ArrayIndexOutOfBoundsException: 100000
at concurrency.BaseLine.accumulate(SynchronizationComparisons.java:89)
at concurrency.Accumulator$Modifier.run(SynchronizationComparisons.java:39)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:744)
Here is code:
import java.util.concurrent.*;
import java.util.concurrent.atomic.*;
import java.util.concurrent.locks.*;
import java.util.*;
import static net.mindview.util.Print.*;
abstract class Accumulator {
public static long cycles = 50000L;
// Number of Modifiers and Readers during each test:
private static final int N = 4;
public static ExecutorService exec = Executors.newFixedThreadPool(N * 2);
private static CyclicBarrier barrier = new CyclicBarrier(N * 2 + 1);
protected volatile int index = 0;
protected volatile long value = 0;
protected long duration = 0;
protected String id = "error";
protected final static int SIZE = 100000;
protected static int[] preLoaded = new int[SIZE];
static {
// Load the array of random numbers:
Random rand = new Random(47);
for (int i = 0; i < SIZE; i++)
preLoaded[i] = rand.nextInt();
}
public abstract void accumulate();
public abstract long read();
private class Modifier implements Runnable {
public void run() {
for (long i = 0; i < cycles; i++)
accumulate();
try {
barrier.await();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
private class Reader implements Runnable {
#SuppressWarnings("unused")
private volatile long value;
public void run() {
for (long i = 0; i < cycles; i++)
value = read();
try {
barrier.await();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
public void timedTest() {
long start = System.nanoTime();
for (int i = 0; i < N; i++) {
exec.execute(new Modifier());
exec.execute(new Reader());
}
try {
barrier.await();
} catch (Exception e) {
throw new RuntimeException(e);
}
duration = System.nanoTime() - start;
printf("%-13s: %13d\n", id, duration);
}
public static void report(Accumulator acc1, Accumulator acc2) {
printf("%-22s: %.2f\n", acc1.id + "/" + acc2.id, (double) acc1.duration / (double) acc2.duration);
}
}
class BaseLine extends Accumulator {
{
id = "BaseLine";
}
public void accumulate() {
value += preLoaded[index++];
if (index >= SIZE)
index = 0;
}
public long read() {
return value;
}
}
class SynchronizedTest extends Accumulator {
{
id = "synchronized";
}
public synchronized void accumulate() {
value += preLoaded[index++];
if (index >= SIZE)
index = 0;
}
public synchronized long read() {
return value;
}
}
class LockTest extends Accumulator {
{
id = "Lock";
}
private Lock lock = new ReentrantLock();
public void accumulate() {
lock.lock();
try {
value += preLoaded[index++];
if (index >= SIZE)
index = 0;
} finally {
lock.unlock();
}
}
public long read() {
lock.lock();
try {
return value;
} finally {
lock.unlock();
}
}
}
class AtomicTest extends Accumulator {
{
id = "Atomic";
}
private AtomicInteger index = new AtomicInteger(0);
private AtomicLong value = new AtomicLong(0);
public void accumulate() {
// Oops! Relying on more than one Atomic at
// a time doesn't work. But it still gives us
// a performance indicator:
int i = index.getAndIncrement();
value.getAndAdd(preLoaded[i]);
if (++i >= SIZE)
index.set(0);
}
public long read() {
return value.get();
}
}
public class SynchronizationComparisons {
static BaseLine baseLine = new BaseLine();
static SynchronizedTest synch = new SynchronizedTest();
static LockTest lock = new LockTest();
static AtomicTest atomic = new AtomicTest();
static void test() {
print("============================");
printf("%-12s : %13d\n", "Cycles", Accumulator.cycles);
baseLine.timedTest();
synch.timedTest();
lock.timedTest();
atomic.timedTest();
Accumulator.report(synch, baseLine);
Accumulator.report(lock, baseLine);
Accumulator.report(atomic, baseLine);
Accumulator.report(synch, lock);
Accumulator.report(synch, atomic);
Accumulator.report(lock, atomic);
}
public static void main(String[] args) {
int iterations = 5; // Default
if (args.length > 0) // Optionally change iterations
iterations = new Integer(args[0]);
// The first time fills the thread pool:
print("Warmup");
baseLine.timedTest();
// Now the initial test doesn't include the cost
// of starting the threads for the first time.
// Produce multiple data points:
for (int i = 0; i < iterations; i++) {
test();
Accumulator.cycles *= 2;
}
Accumulator.exec.shutdown();
}
}
How to solve this trouble?
The array preLoaded is of size 100000. So, the valid index starts from 0 to 99999 since array index starts from 0. You need to swap the statements in method accumulate()
Change this
value += preLoaded[index++]; //index validity is not done
if (index >= SIZE)
index = 0;
to
if (index >= SIZE)
index = 0;
value += preLoaded[index++]; // index validity is done and controlled
This will not make the index go to 100000. It will make it to 0 when it turns 100000 before the index value is accessed.
Note : The above code is vulnerable only in multi-threaded environment. The above code will work fine with single thread.
Change BaseLine class and AtomicTest class:
class BaseLine extends Accumulator {
{
id = "BaseLine";
}
public void accumulate() {
int early = index++; // early add and assign to a temp.
if(early >= SIZE) {
index = 0;
early = 0;
}
value += preLoaded[early];
}
public long read() {
return value;
}
}
class AtomicTest extends Accumulator {
{
id = "Atomic";
}
private AtomicInteger index = new AtomicInteger(0);
private AtomicLong value = new AtomicLong(0);
public void accumulate() {
int early = index.getAndIncrement();
if(early >= SIZE) {
index.set(0);
early = 0;
}
value.getAndAdd(preLoaded[early]);
}
public long read() {
return value.get();
}
}
I suspect that you're running into concurrent executions of BaseLine.accumulate() near the boundary of the preLoaded array.
You've got 4 threads hammering away at an unsynchronized method, which is potentially leading to index being incremented to 100000 by say, Thread 1, and before Thread 1 can set it back to 0, one of Thread 2, 3 or 4 is coming in and attempting to access preLoaded[index++], which fails as index is still 100000.
I was wondering if it is possible to spawn each loop iteration (each iteration into a thread by itself) and finally collect the result. consider this example, nothing fancy in it at all. Just a simple for-loop, but the idea is to extend on it. The body of for loop does not matter, I just filled up with some code. but basically assume it has some expensive calculation which will take few minutes to complete for each iteration. so I want to do each loop calculation in a separate thread.
public class Threadspawns {
private double[] arr = new double[4];
public void calculations(){
for (int i =2; i < 6; i++){
//expensive calculation
arr[i-2]=Math.pow(i,500);
}
}
public static void main(String[] args){
Threadspawns t = new Threadspawns();
long start = System.currentTimeMillis();
t.calculations();
long end = System.currentTimeMillis();
System.out.println(Arrays.toString(t.arr));
System.out.println("time taken "+ (end-start));
}
}
on the same note,
if it is possible to actually split the recursive calls into multiple threads and collect them as they return.
Example is that of fibonacci
public static int fibonacci(int n){
if (n==0)
return 0;
if (n==1)
return 1;
return fibonacci(n-2)+fibonacci(n-1);
}
It is possible that it cannot be done for fibonacci recurive method. but any other example of paralleling recursive calls between threads IF POSSIBLE would be nice to know.
P.S: I have basic knowledge of Thread and Runnable, but wondering if the above is doable
Solution to your first requirement that is moving the expensive calculation into a Callable task. Hope it find it useful:
import java.util.Arrays;
import java.util.concurrent.*;
public class Threadspawns {
private final int THREAD_COUNT = 8;
private final int CALCULATION_COUNT = 60000;
private double[] arr = new double[CALCULATION_COUNT];
public void calculations() {
ExecutorService executorService = Executors.newFixedThreadPool(THREAD_COUNT);
ExecutorCompletionService<Double> completionService = new ExecutorCompletionService<Double>(executorService);
for (int i = 2; i < CALCULATION_COUNT; i++) {
completionService.submit(new Calculation(i));
}
//Get from all Future tasks till all tasks completed
for (int i = 2; i < CALCULATION_COUNT; i++) {
try {
arr[i] = completionService.take().get();
} catch (InterruptedException e) {
e.printStackTrace(); //do something
} catch (ExecutionException e) {
e.printStackTrace(); //do something
}
}
}
private static class Calculation implements Callable<Double> {
private final int num;
private Calculation(int num) {
this.num = num;
}
#Override
public Double call() throws Exception {
return Math.pow(num, 500);
}
}
public static void main(String[] args) {
Threadspawns t = new Threadspawns();
long start = System.currentTimeMillis();
t.calculations();
long end = System.currentTimeMillis();
System.out.println(Arrays.toString(t.arr));
System.out.println("time taken " + (end - start));
}
}