Java threads: how do threads return values - java

I'm a university student of Computer Science and I am familiar with threads in C.
However in Java the OOP makes Threads hard for me to understand.
I've written the following program and need to return values from the independent thread back to the main program.
The main program:
package main;
public class Main {
public static void main(String[] args) {
System.out.println(fibonacci(400));
}
public static int fibonacci(int x) {
Thread p1 = new Thread( new Fibonacci(x-1));
Thread p2 = new Thread( new Fibonacci(x-2));
p1.start();
p2.start();
int result = 0;
// Here I need the returns of the threads
// int result = thread_value1 + thread_value2;
return result;
}
}
The Fibonacci threads:
package main;
public class Fibonacci implements Runnable {
int result;
int x;
public Fibonacci(int parameter) {
x = parameter;
}
#Override
public void run() {
result = fib(x);
}
public int fib(int x) {
if(x == 1) return 1;
if(x == 2) return 1;
return fib(x-1) + fib(x-2);
}
}

The simplest way to achieve this is to save the results to a field in your Fibonacci objects and then read them from there. Note that since many threads will access this data, you need to synchronized access to these fields. In th e case of simple int values, adding the volatile modifier will be enough. It may also make the code clearer if you extend Thread instead of providing Runnable (but this is not neccessary). So your code could look something like this:
public class FibonacciThread extends Thread {
public volatile int result;
int x;
public FibonacciThread(int parameter) {
x = parameter;
}
#Override
public void run() {
result = fib(x);
}
public int fib(int x) {
if(x == 1) return 1;
if(x == 2) return 1;
return fib(x-1) + fib(x-2);
}
}
In main() you then do something like:
FibonacciThread p1 = new FibonacciThread(x-1);
FibonacciThread p2 = new FibonacciThread(x-2);
p1.start();
p2.start();
p1.join();
p2.join();
int result = p1.result + p2.result;
I'm skipping getters/setters and any fancy design for brevity's sake.
The call to Thread.join() is needed in order to wait for the thread to finish so that you can be sure that the result field was calculated before you read its value.

As noted by Sotirios Delimanolis in the comments, you can use Callable and ExecutorService for this, e.g. see this example
Another alternative that may be overkill here, but that is especially useful if the threads are producing more than one value, is to use a BlockingQueue or a ConcurrentLinkedQueue to communicate between threads. This is the basis behind libraries like Akka.
public class Main {
BlockingQueue<Integer> queue = new LinkedBlockingQueue();
public static int fibonacci(int x) {
Thread p1 = new Thread( new Fibonacci(x-1, queue));
Thread p2 = new Thread( new Fibonacci(x-2, queue));
p1.start();
p2.start();
// wait for queues to have values in them, then remove the values
int result = queue.take().intValue() + queue.take().intValue();
return result;
}
}
public class Fibonacci implements Runnable {
int x;
BlockingQueue<Integer> queue;
public Fibonacci(int parameter, BlockingQueue queueParam) {
x = parameter;
queue = queueParam;
}
#Override
public void run() {
// put output in queue
queue.offer(new Integer(fib(x)));
}
}

Related

How do I instantiate two threads of the same object, and have the objects print different things

The goal: So I have a runnable class ThisThat. I instantiate two threads of ThisThat. One prints "This" and one prints "That". The main class is not supposed to determine what it prints.
The question: how do I make a default constructor set two different outputs for two threads of the same class? What can be improved? How can I make it only print this or that instead of both simultaneously?
Desired end result would be a program that runs for about 10 seconds and prints either this or that 10 times. Current output is "this" "that" at the same time, waits about 10 seconds and then repeats 10 times.
import java.util.Random;
public class ThisThat implements Runnable {
private String output;
private int threadNum;
public ThisThat() {
output = "";
}
public ThisThat(int t_Num) {
threadNum = t_Num;
setThisOrThat(threadNum);
}
public void setThisOrThat(int num) {
if (num == 1) {
output = "this";
} else if (num == 2) {
output = "that";
} else {
Random random = new Random();
int randNum = random.nextInt((3) + 1);
setThisOrThat(randNum);
}
}
#Override
public void run() {
for (int i=1; i <= 10; i++) {
try {
System.out.println(getOutput());
Thread.sleep((int)(800));
}
catch(InterruptedException e) {
System.err.println(e);
}
}
}
public String getOutput() { return output; }
public void setOutput(String output) { this.output = output; }
}
class Main {
public static void main(String args[]) {
Thread thread1 = new Thread(new ThisThat(1));
Thread thread2 = new Thread(new ThisThat(2));
thread1.start();
thread2.start();
}
}
One solution is to update the constructor to not take in anything from Main, then create a static volatile or Atomic property within your ThisThat class that is basically a counter changing the values for each thread instance.

synchronized keyword does not work as expected in java [duplicate]

This question already has answers here:
synchronized block for an Integer object
(3 answers)
Closed 6 years ago.
Edit:
I have already found the answer on the stack:
https://stackoverflow.com/a/16280842/3319557
I face a problem with synchronization. I have two following methods:
public synchronized void incrementCounter1() {
counter++;
}
public void incrementCounter2() {
synchronized (counter) {
counter++;
}
}
I test each of those (separately) in many threads. First method behaves as expected, but second (incrementCounter2) is wrong. Can somebody explain why is this happening?
I assume this method is well designed, as I found something lookalike in Java Concurrency in Practice. Snipped from this book:
#ThreadSafe
public class ListHelper<E> {
public List<E> list = Collections.synchronizedList(new ArrayList<E>());
...
public boolean putIfAbsent(E x) {
synchronized (list) {
boolean absent = !list.contains(x);
if (absent)
list.add(x);
return absent;
}
}
}
I use monitor from the Object I am modifying, exactly like in book.
Full code here:
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class SynchronizationTest {
public static final int N_THREADS = 500;
public static final int N_Loops = 5000;
private Integer counter = 0;
Lock l = new ReentrantLock();
public void incrementCounter0() {
counter++;
}
public synchronized void incrementCounter1() {
counter++;
}
public void incrementCounter2() {
synchronized (counter) {
counter++;
}
}
public void incrementCounter3() {
try {
l.lock();
counter++;
} finally {
l.unlock();
}
}
private interface IncrementStrategy {
void use(SynchronizationTest t);
}
private static class IncrementingRunnable implements Runnable {
SynchronizationTest synchronizationTest;
IncrementStrategy methodToUse;
public IncrementingRunnable(SynchronizationTest synchronizationTest, IncrementStrategy methodToUse) {
this.synchronizationTest = synchronizationTest;
this.methodToUse = methodToUse;
}
#Override
public void run() {
for (int i = 0; i < N_Loops; i++) {
methodToUse.use(synchronizationTest);
}
}
}
public void test(IncrementStrategy methodToUse, String methodName) {
counter = 0;
Thread[] threads = new Thread[N_THREADS];
for (int i = 0; i < N_THREADS; i++) {
threads[i] = new Thread(new IncrementingRunnable(this, methodToUse));
threads[i].start();
}
for (int i = 0; i < N_THREADS; i++) {
try {
threads[i].join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(methodName + " diff than expected " + (counter - N_THREADS * N_Loops));
}
public void test() {
test(t -> t.incrementCounter0(), "incrementCounter0 (expected to be wrong)");
test(t -> t.incrementCounter1(), "incrementCounter1");
test(t -> t.incrementCounter2(), "incrementCounter2");
test(t -> t.incrementCounter3(), "incrementCounter3");
}
public static void main(String[] args) {
new SynchronizationTest().test();
}
}
I know, that ExecutorService should be used, whole problem can be solved with AtomicLong, but it is not the point of this question.
Output of the code is:
incrementCounter0 (expected to be wrong) diff than expected -1831489
incrementCounter1 diff than expected 0
incrementCounter2 diff than expected -599314
incrementCounter3 diff than expected 0
PS.
If I add the field to SynchronizationTest
Object counterLock = new Object();
and change
incrementCounter2 to:
public void incrementCounter2() {
synchronized (counterLock) {
counter++;
}
}
Then incremetCounter2 works as expected.
You're synchronizing on different objects
incrementCounter1 synchronizes on this, while incrementCounter2 synchronizes on the counter Integer object itself.
You are trying to use two lock monitors (assuming counter is an Object, perhaps Integer?)
public class Foo {
// Uses instance of Foo ("this")
public synchronized void incrementCounter1() {
counter++;
}
public void incrementCounter2() {
// uses counter object as lock monitor
synchronized (counter) {
counter++;
}
}
}
I am not sure what you are trying to achieve with counter++ as it seems counter is of type Integer?
Few options to fix your problem:
Use a the same lock monitor
You might want to look into AtomicInteger
Use the lock API (e.g., ReentrantReadWriteLock)
Hideous.
synchronized void method(...
Synchronizes on the this Object.
synchronized(object) {
...
Synchronizes on object.
Now:
synchronized (counter) {
++counter;
must also synchronize on an Object, but counter is a primitive type, an int.
What happens, is that counter is boxed in an Integer.
When counter is 0 .. 127 the Integer object retrieved is everytime different, but shared. For say 1234 a new unique Integer object is created, and synchronized has no effect whatsoever. (Integer being immutable.)
I would call this almost a language error, something for FindBugs to find.

Accessing two synchronized block with two thread simultaneously

Could anyone tell me how to accessing one method simultaneously with 2 thread, this method have 2 parameter and 2 synchronized block. and what I want is, one thread execute first synchronized block, and the other thread execute the second synchronized block.
public class myThread{
public static class TwoSums implements Runnable{
private int sum1 = 0;
private int sum2 = 0;
public void add(int a, int b){
synchronized(this){
sum1 += a;
String name = Thread.currentThread().getName();
System.out.println("Thread name that was accessing this code 1 : "+name);
}
synchronized(this){
sum2 += b;
String name = Thread.currentThread().getName();
System.out.println("Thread name that was accessing this code 2 : "+name);
}
}
#Override
public void run() {
add(10,20);
}
}
public static void main(String[] args) {
TwoSums task = new TwoSums();
Thread t1 = new Thread(task, "Thread 1");
Thread t2 = new Thread(task, "Thread 2");
t1.start();
t2.start();
}
}
This code containing some code from : http://tutorials.jenkov.com/java-concurrency/race-conditions-and-critical-sections.html
The instructions are processed sequentially by any thread and the synchronization blocks don't make any exception. The following code does what you are asking for but looks just as an exercise without any real meaningful application
public static class TwoSums implements Runnable {
private int sum1 = 0;
private int sum2 = 0;
public void add(int a, int b) {
if ("Thread 1".equals(Thread.currentThread().getName())) {
synchronized (this) {
sum1 += a;
String name = Thread.currentThread().getName();
System.out.println("Thread name that was accessing this code 1 : " + name);
}
}
if ("Thread 2".equals(Thread.currentThread().getName())) {
synchronized (this) {
sum2 += b;
String name = Thread.currentThread().getName();
System.out.println("Thread name that was accessing this code 2 : " + name);
}
}
}
#Override
public void run() {
add(10, 20);
}
}
In order to achieve that goal (I'm not going to discuss if what you're doing is right or wrong because I suppose that you're just learning how things work) you need to use the ReentranLock interface and its implementation Lock class:
Lock lock = new ReentrantLock();
You should declare this object in your TwoSum class and use the lock object inside of your add method. ReentrantLock interface has a method called tryLock which will try to get the lock of the object where it's called and it will return a boolean value true if it was successful or false otherwise. So for the first thread it will return true, but for the second one it will return false. So all you need to put is a validation
if(lock.tryLock()) //Execute block code 1
else // Execute block code 2

Java Threads with ConcurrentModificationException

I'm currently working on my first multithreaded software - a program, which calculates prime numbers...
Basically I create n (number of Threads) runnables. These runnables are added to an ArrayList. They check, whether a number is a prime. If the number is a prime I add it into an long array for later use. Since I want the primes to be in correct order in this array I need specific Threads to wait for others. I do this by looping through the ArrayList (see above) and wait for the threads, which check a lower number.
After a thread is done I want to remove it from the given ArrayList, but I cant since the other threads are still looping through it (This is the reason why the ConcurrentModificationException occurs I guess - This is my first time working with threads...).
I honestly hope that any of you guys can help me :)
Thank your really much!
Matthias
My runnable class (I just create four objects of this class in the main method):
import java.util.ArrayList;
public class PrimeRunnable implements Runnable {
//Static Util
public static ArrayList<PrimeRunnable> runningThreads = new ArrayList<PrimeRunnable>();
public static long[] primes;
public static int nextFreeIndex = 1;
public static long nextPossiblePrime = 3;
//Object specific
private long numberToCheck;
private Thread primeThread;
private String threadName;
private long threadID;
public PrimeRunnable() {
numberToCheck = nextPossiblePrime;
increaseNextPossiblePrime();
threadName = "ThreadToCheck" + numberToCheck;
threadID = numberToCheck;
runningThreads.add(this);
}
#Override
public void run() {
boolean isPrime = true;
double sqrtOfPossiblePrime = Math.sqrt(numberToCheck);
long lastDevider = 0;
for(int index = 0; index < nextFreeIndex; index++) {
lastDevider = primes[index];
if(numberToCheck%primes[index] == 0) {
isPrime = false;
break;
}
if(primes[index] > sqrtOfPossiblePrime) {
break;
}
}
while(lastDevider < sqrtOfPossiblePrime) {
lastDevider += 1;
if(numberToCheck%lastDevider == 0) {
isPrime = false;
break;
}
}
if(isPrime) {
//Wait for lower Threads.
for(PrimeRunnable runnable : runningThreads) {
if(runnable.getThreadID() < this.getThreadID()) {
try {
runnable.primeThread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
primes[nextFreeIndex] = numberToCheck;
increaseNextFreeIndex();
System.out.println(numberToCheck);
}
runningThreads.remove(this);
}
public void start() {
if(primeThread == null) {
primeThread = new Thread(this, threadName);
}
primeThread.start();
}
public void reset() {
numberToCheck = nextPossiblePrime;
increaseNextPossiblePrime();
threadName = "ThreadToCheck" + numberToCheck;
threadID = numberToCheck;
//No need to readd into runningThread, since we only manipulate an already existing object.
primeThread = new Thread(this, threadName);
primeThread.start();
}
public static void setUpperBorder(int upperBorder) {
if(primes == null) {
primes = new long[upperBorder];
primes[0] = 2;
} else {
System.err.println("You are not allowed to set the upper border while running.");
}
}
public long getNumberToCheck() {
return numberToCheck;
}
private void increaseNextPossiblePrime() {
nextPossiblePrime += 2;
}
private void increaseNextFreeIndex() {
nextFreeIndex += 2;
}
public long getThreadID() {
return threadID;
}
public boolean isAlive() {
return primeThread.isAlive();
}
}
I was able to replicate the issue and fix it using Java implementation of a concurrent list CopyOnWriteArrayList
Here's my main class
public class PrimeRunnableMain {
public static void main(String[] args) {
PrimeRunnable.setUpperBorder(10);
PrimeRunnable primeRunnable1 = new PrimeRunnable();
PrimeRunnable primeRunnable2 = new PrimeRunnable();
PrimeRunnable primeRunnable3 = new PrimeRunnable();
PrimeRunnable primeRunnable4 = new PrimeRunnable();
primeRunnable1.start();
primeRunnable2.start();
primeRunnable3.start();
primeRunnable4.start();
}
}
and here's PrimeRunnable
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
public class PrimeRunnable implements Runnable {
// Static Util
public static List<PrimeRunnable> runningThreads = new CopyOnWriteArrayList<PrimeRunnable>();
public static long[] primes;
public static int nextFreeIndex = 1;
public static long nextPossiblePrime = 3;
// Object specific
private long numberToCheck;
private Thread primeThread;
private String threadName;
private long threadID;
public PrimeRunnable() {
numberToCheck = nextPossiblePrime;
increaseNextPossiblePrime();
threadName = "ThreadToCheck" + numberToCheck;
threadID = numberToCheck;
runningThreads.add(this);
}
#Override
public void run() {
boolean isPrime = true;
double sqrtOfPossiblePrime = Math.sqrt(numberToCheck);
long lastDevider = 0;
for (int index = 0; index < nextFreeIndex; index++) {
lastDevider = primes[index];
if (numberToCheck % primes[index] == 0) {
isPrime = false;
break;
}
if (primes[index] > sqrtOfPossiblePrime) {
break;
}
}
while (lastDevider < sqrtOfPossiblePrime) {
lastDevider += 1;
if (numberToCheck % lastDevider == 0) {
isPrime = false;
break;
}
}
if (isPrime) {
// Wait for lower Threads.
for (PrimeRunnable runnable : runningThreads) {
if (runnable.getThreadID() < this.getThreadID()) {
try {
runnable.primeThread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
primes[nextFreeIndex] = numberToCheck;
increaseNextFreeIndex();
System.out.println(numberToCheck);
}
runningThreads.remove(this);
}
public void start() {
if (primeThread == null) {
primeThread = new Thread(this, threadName);
}
primeThread.start();
}
public void reset() {
numberToCheck = nextPossiblePrime;
increaseNextPossiblePrime();
threadName = "ThreadToCheck" + numberToCheck;
threadID = numberToCheck;
// No need to readd into runningThread, since we only manipulate an
// already existing object.
primeThread = new Thread(this, threadName);
primeThread.start();
}
public static void setUpperBorder(int upperBorder) {
if (primes == null) {
primes = new long[upperBorder];
primes[0] = 2;
} else {
System.err
.println("You are not allowed to set the upper border while running.");
}
}
public long getNumberToCheck() {
return numberToCheck;
}
private void increaseNextPossiblePrime() {
nextPossiblePrime += 2;
}
private void increaseNextFreeIndex() {
nextFreeIndex += 2;
}
public long getThreadID() {
return threadID;
}
public boolean isAlive() {
return primeThread.isAlive();
}
}
What about a PrimeListener class that contains a synchronized method publishPrime that inserts the prime in the correct position in the list? Inserting at the right position into the list should not take too much time, if you start at the last index of a LinkedList.
Alternatively you could also insert it into a SortedSet (implementation: TreeSet). I presume you don't want any duplicate primes anyway. In that case synchronizedSortedSet may be directly used instead of the listener.
Note that you still seem rather stuck on lower level structures. When programming concurrently on Java it pays off to use the higher level constructs (executors, futures, concurrent queue's etc. etc.).
The main distinction between fail-fast and fail-safe iterators is
whether or not the collection can be modified while it is being
iterated. Fail-safe iterators allow this; fail-fast iterators do not.
Fail-fast iterators operate directly on the collection itself. During
iteration, fail-fast iterators fail as soon as they realize that the
collection has been modified (i.e., upon realizing that a member has
been added, modified, or removed) and will throw a
ConcurrentModificationException. Some examples include ArrayList,
HashSet, and HashMap (most JDK1.4 collections are implemented to be
fail-fast). Fail-safe iterates operate on a cloned copy of the
collection and therefore do not throw an exception if the collection
is modified during iteration. Examples would include iterators
returned by ConcurrentHashMap or CopyOnWriteArrayList.

multithreading java xync

I'm new to multithreading. I need to calculate integral by partial sums using multiple threads. I want to find out if all threads finished calculating to show general sum, I'm doing it using sleep(500) but it's stupid. How can i do it by the right way?
public class MainClass {
private static int threadCount=10;
public static double generalSum=0;
private static ArrayList<CalculatingThread> threads;
public static void main(String[] args){
Calculator.setA(0);
Calculator.setB(2);
Calculator.setN(500);
threads=new ArrayList<CalculatingThread>();
int div=500/threadCount;
for (int i=0; i<div;i++){
CalculatingThread thread=new CalculatingThread();
thread.setJK(i*10,(i+1)*10-1);
thread.start();
threads.add(thread);
}
try {
Thread.currentThread().sleep(500);
System.out.println(generalSum);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class CalculatingThread extends Thread {
private int j;
private int k;
#Override
public void run(){
System.out.println("Partial sum: " + Calculator.calcIntegral(j, k));
Calculator.addToSumm(Calculator.calcIntegral(j, k));
//this.notify();
}
public void setJK(int j,int k) {
this.j = j;
this.k=k;
}
}
public class Calculator {
private static double a;
private static double b;
private static int n;
private static double InFunction(double x){
return Math.sin(x);
}
private double sum=0;
public static void setA(double a) {
Calculator.a = a;
}
public static void setB(double b) {
Calculator.b = b;
}
public static void setN(int n) {
Calculator.n = n;
}
public static double calcIntegral(int j,int k)
{
double result, h;
int i;
h = (b-a)/n; //Шаг сетки
result = 0;
for(i=j; i <= k; i++)
{
result += InFunction(a + h * i - h/2); //Вычисляем в средней точке и добавляем в сумму
}
result *= h;
return result;
}
public static synchronized void addToSumm(double sum){
MainClass.generalSum+=sum;
}
}
P.S. sorry, i know code is stupid, i will refactor it later
Replace
Thread.currentThread().sleep(500);
with
for (Thread thread : threads) {
thread.join();
}
This will make main thread to wait until all the created threads get completed. Also you can refer wait until all threads finish their work in java
you can use join to make the main thread wait for the others:
The join method allows one thread to wait for the completion of
another. If t is a Thread object whose thread is currently executing,
t.join(); causes the current thread to pause execution until t's
thread terminates. Overloads of join allow the programmer to specify a
waiting period. However, as with sleep, join is dependent on the OS
for timing, so you should not assume that join will wait exactly as
long as you specify.
save every thread you create in an array and then do join on them
so your main should look like
public class MainClass {
private static int threadCount=10;
public static double generalSum=0;
private static ArrayList<CalculatingThread> threads;
public static void main(String[] args){
Calculator.setA(0);
Calculator.setB(2);
Calculator.setN(500);
threads=new ArrayList<CalculatingThread>();
int div=500/threadCount;
for (int i=0; i<div;i++){
CalculatingThread thread=new CalculatingThread();
thread.setJK(i*10,(i+1)*10-1);
thread.start();
threads.add(thread);
}
try {
for (Thread curr: threads) {
curr.join();
}
System.out.println(generalSum);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
now on a side note, no series program is using sleep when it wants to wait. sleep is only used when you actually need a delay in a background thread
P.S.
do not refactor the code. it is excellent to post it like that, so i can see every mistake you do if u do. a lot better then most people posting only 1 line and then there is nothing i can do but ask for more details

Categories

Resources