This thread program shows me different answers every time - java

This is a Java Program to Find The Number with Largest Divisors from 1-500000.
public class Medium2 {
static int count1 = 1;
static int count2 = 1;
static int big_count = 0;
static int big = 0;
Main method
public static void main(String[] args) {
Runnable runnable1 = new Runnable() {
public void run() {
The implementation goes here
for (int num = 1; num <= 500000; num++) {
for (int i = 2; i <= num; i++) {
if (num % i == 0) { //Actual Logic
count1++;
}
}
if (count1 > big_count) {
big_count = count1; //Number of Divisors
big = num; //Largest Number
}
count1 = 1;
}
}
};
And the thread execution
Thread thread1 = new Thread(runnable1); //Threads
Thread thread2 = new Thread(runnable1);
thread1.start();
thread2.start();
try {
thread1.join();
thread2.join();
} catch (InterruptedException ie) {
;
}
System.out.println("Biggest: " + big + "\nNumber of Divisors for " + big + " = " + big_count);
}
}
But it gives different answers every time. The actual answer is : 498960 and 200 Divisors

Concerning your goal, your implementation should probably have problems. Since big_count and big is common for both threads and don't have any protection when threads are trying to modify those, your program should create errors.
Other than that, you are also not utilizing 2 threads, since both threads are doing calculation from 1 to 500000.
Since your calculation logic seems ok, you should get your desired output when you try with single thread.
If you want it to do by two threads, you can easily try this. (just to verify, not the nicest way)
You should have big_count1, big1 and big_count2, big2. So that variables whose names end with '1' is only using by thread1 and variables whose names end with '2' is only using by thread2.
Assign thread1 to check from 1 to 250000 and thread2 to from 250001 to 500000.
After join() s, just compare big_count1 and big_count2, then you can deduce the final answer. :))

Related

Multithreading with the thread join

I work in the multithreading problem where 2 threads are started from the main. The code is provided below,
package com.multi;
public class App {
private int count = 0;
public void doWork() {
Thread thread1 = new Thread(new Runnable() {
public void run() {
for (int i = 0; i < 10000; i++) {
count++;
}
}
});
Thread thread2 = new Thread(new Runnable() {
public void run() {
for (int i = 0; i < 10000; i++) {
count++;
}
}
});
thread1.start();
thread2.start();
try {
thread1.join();
thread2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Count is: " + count);
}
public static void main(String[] args) {
App worker = new App();
worker.doWork();
}
}
In the book, it informs that there is a possibility that the count value can be printed less than 20000 in some cases. They provided some explanation but even after reading for few times, I was unable to comprehend that completely. Like there is a try block that join the threads and that meant to ensure to complete both for loops.
a. In which circumstances, the count can be printed less than the 20000 and why both of the threads won't increase the count value?
b. If I wrote like
private volatile int count = 0;
private AtomicInteger count = 0;
will these essentially solve the issue?
Consider this sequence
count is 1
thread1 reads count 1 into local var x
thread2 reads count 1 into local var y
thread1 increments x to 2
thread1 writes x value 2 to count
thread2 increments y to 2
thread2 writes the y value 2 to count
When you do count++, it is a read from the field count, an addition of 1 to the value, and then a write of the result back to the field count, so my example sequence is essentially what can happen in your code.
In my example sequence, even though the field was incremented twice, the count is just 2, and not 3.
This happens because both threads are reading and writing from the same field at the same time.

Volatile keyword atomicity

I am trying to learn volatile field modifier in multi-threading. I came across this statement:
Volatile is preferred in cases when one thread reads and writes a shared variable and other threads just read the same. Whereas if there are more than 2 threads performing read and write both on the shared variable then only volatile is not enough, you need to have synchronization as well.
I am aware that volatile provides visibility and happens-before guarantee, but is it possible to give a simple small example of code to demonstrate the above statements wherein a synchronized block is needed?
public class TwoInts {
private volatile int i1;
private volatile int i2;
public void set(int i1, int i2) {
this.i1 = i1;
this.i2 = i2;
}
public boolean same() {
return i1 == i2;
}
}
Now, if you have one thread doing this:
while (true) {
twoInts.set(i, i);
i++;
}
and a second thread doing this:
while (true) {
if (!twoInts.same()) {
System.out.println("Ooops!!");
}
}
then you will observe the problem that the quoted text is talking about. And if you rewrite the TwoInts class to make the methods synchronized then the "Oooops!!" messages will stop.
Let's say you have int i and two threads, you expect every one read i and set i = i + 1.
Like this:
public class Main {
private static volatile int i = 0;
public static void main(String[] args) throws Exception{
Runnable first = new Runnable() {
#Override
public void run() {
System.out.println("Thread_1 see i = " + i);
i++;
System.out.println("Thread_1 set i = " + i);
}
};
Runnable second = new Runnable() {
#Override
public void run() {
System.out.println("Thread_2 see i = " + i);
i++;
System.out.println("Thread_2 set i = " + i);
}
};
new Thread(first).start();
new Thread(second).start();
}
}
The result is:
Thread_1 see i = 0
Thread_2 see i = 0
Thread_1 set i = 1
Thread_2 set i = 2
As you see, Thread_2 get 0 and set 2(because Thread_1 has updated i to 1), which is not expected.
After adding syncronization,
public class Main {
private static volatile int i = 0;
public static void main(String[] args) throws Exception{
Runnable first = new Runnable() {
#Override
public void run() {
synchronized (Main.class) {
System.out.println("Thread_1 see i = " + i);
i++;
System.out.println("Thread_1 set i = " + i);
}
}
};
Runnable second = new Runnable() {
#Override
public void run() {
synchronized (Main.class) {
System.out.println("Thread_2 see i = " + i);
i++;
System.out.println("Thread_2 set i = " + i);
}
}
};
new Thread(first).start();
new Thread(second).start();
}
}
It works:
Thread_2 see i = 0
Thread_2 set i = 1
Thread_1 see i = 1
Thread_1 set i = 2
There are a lot of such examples... Here's one:
volatile int i = 0;
// Thread #1
while (true) {
i = i + 1;
}
// Thread #2
while (true) {
Console.WriteLine(i);
}
In this case, Thread #1 and Thread #2 are both reading the variable i, but only Thread #1 is writing to it. Thread #2 will always see an incrementing value of i.
Without the volatile keyword, you will occasionally see strange behavior, usually on multiprocessor machines or multicore CPUs. What happens (simplifying slightly here) is that Thread #1 and #2 are each running on their own CPU and each gets it's own copy of i (in it's CPU cache and/or registers). Without the volatile keyword, they may never update each other about the changed value.
Contrast with this example:
static volatile int i = 0;
// Thread #1
while (true) {
i = i + 1;
}
// Thread #2
while (true) {
if (i % 2 == 0)
i == 0;
else
Console.WriteLine(i);
}
So here, Thread #1 is trying to monotonically increment i, and Thread #2 is either going to set i to 0 (if i is even) or print it to the console if i is odd. You would expect that Thread #2 could never print an even number to the console, right?
It turns out that that is not the case. Because you have no synchronization around the access to i, it is possible that Thread #2 sees an odd value, moves to the else branch, and then Thread #1 increments the value of i, resulting in Thread #2 printing an even number.
In this scenario, one way of addressing the problem is to use basic locking as a form of synchronization. Because we cannot lock on a primitive, we introduce a blank Object to lock on:
static volatile int i = 0;
static Object lockOnMe = new Object();
// Thread #1
while (true) {
lock (lockOnMe) {
i = i + 1;
}
}
// Thread #2
while (true) {
lock (lockOnMe) {
if (i % 2 == 0)
i == 0;
else
Console.WriteLine(i);
}
}

Why are my threads not synchronizing?

I am trying to get a grasp on synchronizing threads, but I don't understand the problem I'm encountering.
Can someone please help me diagnose this or, even better, explain how I can diagnose this for myself?
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CyclicBarrier;
public class Controller {
public static void main(String[] args) {
int numThreads = 0;
List<Thread> threads = new ArrayList<>();
if (args.length > 0) {
numThreads = Integer.parseInt(args[0]);
}
else {
System.out.println("No arguments");
System.exit(1);
}
CyclicBarrier barrier = new CyclicBarrier(numThreads);
int arr[][] = new int[10][10];
for (int i = 0; i < numThreads; i++) {
Thread newThread = new Thread(new ThreadableClass(barrier, arr));
threads.add(newThread);
}
for (Thread thread : threads) {
thread.start();
}
}
}
There is a main method (above) which accepts the number of threads I want as a command line argument. And there is a work-flow (below) which I am aiming to have increment all elements in a 2D array and print the array before the next thread has its chance to do the same:
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
public class ThreadableClass implements Runnable {
private CyclicBarrier barrier;
private int arr[][];
public ThreadableClass(CyclicBarrier barrier, int[][] arr) {
this.barrier = barrier;
this.arr = arr;
}
#Override
public void run() {
long threadId = Thread.currentThread().getId();
System.out.println(threadId + " Starting");
for (int i = 0; i < 10; i++) {
changeArray();
try {
barrier.await();
} catch (InterruptedException | BrokenBarrierException e) {
e.printStackTrace();
}
}
}
private synchronized void changeArray() {
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr.length; j++) {
arr[i][j]++;
}
}
printArray();
}
private synchronized void printArray() {
System.out.println(Thread.currentThread().getId() + " is printing: ");
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr.length; j++) {
System.out.print(arr[i][j] + " ");
}
System.out.println();
}
}
}
Imagining the size of the array is 2x2, the expected output would look something like this:
1 1
1 1
2 2
2 2
3 3
3 3
4 4
4 4
...
...
(10 * numThreads)-1 (10 * numThreads)-1
(10 * numThreads)-1 (10 * numThreads)-1
(10 * numThreads) (10 * numThreads)
(10 * numThreads) (10 * numThreads)
Instead, all threads increment the array, and begin printing over one another.
There is nothing surprising about the result. You create n threads. You tell all threads to start. Each threads run() starts with:
long threadId = Thread.currentThread().getId();
System.out.println(threadId + " Starting");
...changeArray();
going to change that shared array. After writing to the array, you try to sync (on that barrier). Its too late then!
The point is: you have 10 different ThreadableClass instances. Each one is operating on its own! The synchronized key word ... simply doesn't provide any protection here!
Because: synchronized prevents two different threads calling the same method on the same object. But when you have multiple objects, and your threads are calling that method on those different objects, than there is no locking! What your code does boils down to:
threadA to call changeArray() .. on itself
threadB to call changeArray() .. on itself
threadC to call changeArray() .. on itself
...
In other words: you give n threads access to that shared array. But then you allow those n threads to enter changeArray() at the same time.
One simple fix; change
private synchronized void changeArray() {
to
private void changeArray() {
synchronized(arr) {
In other words: make sure that the n threads have to lock on the same monitor; in that case the shared array.
Alternatively: instead of making changeArray() a method in that ThreadableClass ... create a class
ArrayUpdater {
int arr[] to update
synchronized changeArray() ...
Then create one instance of that class; and give that same instance to each of your threads. Now the sync'ed method will prevent multiple threads to enter!
Because you are providing new instance for each theard using new ThreadableClass(barrier, arr), basically, all the theadrs are using different ThreadableClass objects, so your code synchronized methods run parallely, so you need to use a single ThreadableClass object as shown below:
ThreadableClass threadableClass= new ThreadableClass(barrier, arr);
for (int i = 0; i < numThreads; i++) {
Thread newThread = new Thread(threadableClass);
threads.add(newThread);
}
The important point is synchronization is all about providing access (i.e., key) to an object for a single thread at a time. If you are using a different object for each thread, threads don't wait for the key because each thread has got its own key (like in your example).

which thread finished first in concurrent threads?

I am new in concurrent threads in java. I am trying to code a simple horse race simulation.
I want to know which thread finished first.
This code below throws an error: incompatible types: Thread cannot be converted to Gate
winner = (Gate)Thread.currentThread();
Gate.java
public class Gate implements Runnable{
public String horseName;
public final int GATE_DISTANCE = 20;
public final int FINISH_LINE_DISTANCE = 100;
public CyclicBarrier barrier;
public Gate(CyclicBarrier barrier,String horseName){
this.horseName = horseName;
this.barrier = barrier;
}
public void run(){
//Walk all horses to respective racing gates before starting race
for(int distanceCovered = 0; distanceCovered < GATE_DISTANCE;){
distanceCovered += gallop();
int distanceLeft = GATE_DISTANCE - distanceCovered;
if(distanceLeft < 0){
distanceLeft = 0;
}
System.out.println(horseName + "\t\tgate distance left " + distanceLeft);
if(distanceLeft == 0){
break;
}
}
//Wait for all horses to be at racing gates
try{
barrier.await();
}
catch(InterruptedException ie){
System.out.println("INTERRUPTED");
}
catch(BrokenBarrierException bbe){
System.out.println("BROKEN");
}
//ACTUAL HORSE RACE
for(int distanceCovered = 0; distanceCovered < FINISH_LINE_DISTANCE;){
distanceCovered += gallop();
int distanceLeft = FINISH_LINE_DISTANCE - distanceCovered;
if(distanceLeft < 0){
distanceLeft = 0;
}
System.out.println(horseName + "\t\tgate distance left " + distanceLeft);
if(distanceLeft == 0){
break;
}
}
Main.done();
}
public int gallop(){
final int MIN_GALLOP = 1,
MAX_GALLOP = 10;
Random random = new Random();
int gallopRange = MAX_GALLOP - MIN_GALLOP + 1;
int totalGallop = random.nextInt(gallopRange) + MIN_GALLOP;
return totalGallop;
}
}
GateMain.java
public class GateMain{
private static Gate winner = null;
public static void main(String[] args) {
int horseCount = 5;
List<String> horseNames = new ArrayList<String>();
List<Thread> RG = new ArrayList<Thread>();
horseNames.add("Red Bullet");
horseNames.add("Green Furious");
horseNames.add("Pink Mirage");
horseNames.add("Blue Dash");
horseNames.add("Yellow Burst");
Scanner scan = new Scanner(System.in);
final CyclicBarrier cb = new CyclicBarrier(horseCount,new Runnable(){
public void run(){
System.out.print("\nALL HORSES ARE IN THEIR RESPECTIVE RACING GATES");
System.out.println("\nRACE BEGIN!!!\n");
}
});
for(int horseCtr = 0; horseCtr < horseCount; horseCtr++){
Gate rg = new Gate(cb,horseNames.get(horseCtr));
Thread thread = new Thread(rg);
thread.start();
RG.add(thread);
}
for(Thread thread: RG){
try{
thread.join();
}
catch(InterruptedException ie){
System.out.println("Thread Interrupted");
}
}
System.out.println(winner.horseName + "\t\t\twins!");
}
synchronized static void done(){
if(winner == null){
winner = (Gate)Thread.currentThread();
}
}
}
I would use a global AtomicInteger.
public static AtomicInteger finishLine = new AtomicInteger(0);
Each horse (thread) should have its own place variable,
int place;
and when a horse finishes the race, it sets its own place:
place = finishLine.incrementAndGet();
The first horse to reach the finish line will get place=1, the second horse, place=2, and so on. Then the main() routine must then examine each horse to find out which one has place=1. That'll be the winner.
Here's a different idea, inspired by the finish-line of a cross-country foot race: Instead of an AtomicInteger, use a thread-safe queue.
public static ArrayBlockingQueue<Horse> chute =
new ArrayBlockingQueue<>(NUMBER_OF_HORSES);
When each horse reaches the finish line, it enters the chute.
chute.add(this);
This way, there is no need to explicitly wait for the race to end, and there is no need to explicitly sort the finishers:
Horse win = chute.take(); //waits for the first horse to finish
Horse place = chute.take(); //waits for the second horse
Horse show = chute.take(); //...
However, just synchronizing here will not work, according to the rules of Java. You have to synchronize the update that you want the thread to read, as well. Depending on what variable is, that may or may not be a problem.
You may need to think out your threading model a bit more, and describe here what you want to do. If you were unaware of mutual exclusion, you may not be ready to design threaded code.
if you're trying to access an instance field from a static member, I have to wonder how you got the code to compile.
Thread.currentThread() returns the actual Thread object you (or some other library code) created. That can be a Gate thread, but it all depends on the Thread object it is running in. Safest is to use instanceof to check first.
According to docs Thread.currentThread() returns a reference to the current thread, not the object. So, you should look for reference to the object i.e this keyword.
You wish to have winner as a private member. You can't change it from run() in another class. So, you can pass the current object from run() as an argument to a method in GateMain by this.
You can edit the done() method as:
synchronized static void done(Gate new_gate){
if(winner == null){
winner = new_gate;
}
}
Replace the line Main.done() with Main.done(this)

The main thread randomly doesn't reach end (trying to sum natural numbers in concurrent threads) [duplicate]

This question already has an answer here:
Loop doesn't see value changed by other thread without a print statement
(1 answer)
Closed 7 years ago.
I have the following code to find the sum of natural numbers from 1 to 5000. It's a simple exercise to practice concurrency.
public static void main(String[] args) throws InterruptedException {
final int[] threadNb = new int[] {5};
final Integer[] result = new Integer[1];
result[0] = 0;
List<Thread> threads = new LinkedList<>();
IntStream.range(0, threadNb[0]).forEach(e -> {
threads.add(new Thread(() -> {
int sum = 0;
int idx = e * 1000 + 1;
while (!Thread.interrupted()) {
if (idx <= (e + 1) * 1000) {
sum += idx++;
} else {
synchronized(result) {
result[0] += sum;
System.err.println("sum found (job " + e + "); sum=" + sum + "; result[0]=" + result[0] + "; idx=" + idx);
Thread.currentThread().interrupt();
}
}
}
synchronized(result) {
System.err.println("Job " + e + " done. threadNb = " + threadNb[0]);
threadNb[0]--;
System.err.println("threadNb = " + threadNb[0]);
}
}));
});
threads.forEach(Thread::start);
//noinspection StatementWithEmptyBody
while(threadNb[0] > 0);
System.out.println("begin result");
System.out.println(result[0]);
System.out.println("end result");
}
Sometimes, when I run the code, the last 3 System.out.println() are not displayed. If I put a statement in the while(threadNb[0] > 0), like another System.out.println(), my problem never happen again.
Can anyone explain me this behaviour?
Thanks in advance for any help
Nothing about how the threadNb variable is declared tells the JVM that it needs to make updates to it visible to other threads. At what point updates to your variable become visible to other threads is entirely up to the JVM implementation, it can make them visible or not depending on circumstances. Also, the JIT is free to re-order or optimize away code if it thinks it can get away with it, and it bases its decisions on the visibility rules. So it's hard to say exactly what happens here because the behavior is left unspecified by the Java language specs, but definitely you're having a problem where your worker threads' updates are usually not getting seen by the main thread.
If you replace the arrays with AtomicInteger then the updates are guaranteed to become visible to other threads. (Volatile works too, but AtomicInteger is preferred. In order to use volatile you have to make the variable an instance or class member.) If you save the updated values in a local variable then you don't need synchronization:
import java.util.*;
import java.util.stream.*;
import java.util.concurrent.atomic.*;
public class SumNumbers {
public static void main(String[] args) throws InterruptedException {
AtomicInteger threadNb = new AtomicInteger(5);
AtomicInteger result = new AtomicInteger(0);
List<Thread> threads = new LinkedList<>();
IntStream.range(0, threadNb.intValue()).forEach(e -> {
threads.add(new Thread(() -> {
int sum = 0;
int idx = e * 1000 + 1;
while (!Thread.currentThread().isInterrupted()) {
if (idx <= (e + 1) * 1000) {
sum += idx++;
} else {
int r = result.addAndGet(sum);
System.out.println("sum found (job " + e + "); sum="
+ sum + "; result=" + r
+ "; idx=" + idx);
Thread.currentThread().interrupt();
}
}
System.out.println("Job " + e + " done.");
int threadNbVal = threadNb.decrementAndGet();
System.out.println("Job " + e + " done, threadNb = " + threadNbVal);
}));
});
threads.forEach(Thread::start);
//noinspection StatementWithEmptyBody
while(threadNb.intValue() > 0);
System.out.println("result=" + result.intValue());
}
}
where you can see the updates become visible.
Busy waiting is not preferred since it wastes CPU cycles. You do see it in lock-free programming, but it is not a good thing here. Thread#join will work or you can use a CountdownLatch.
Be aware that using Thread#interrupted() clears the interrupted flag. Usually it's used when you're about to throw InterruptedException, otherwise it's better to use Thread.currentThread().isInterrupted(). It doesn't hurt anything in this specific case because the while loop test is the only thing using the flag, so whether it gets cleared is irrelevant.
The most likely explanation is that the compiler optimizes your code so that the value of threadNb[0] is cached. Therefore, the main thread may not see updates done by other threads. Making your counter volatile can help to solve this problem.
However, the current approach with a busy wait is generally not the best solution. You should use the join() method of the class Thread to let your main thread wait till each of them has ended.
For example:
for(Thread t: threads) {
try{
t.join();
} catch(InterruptedException e) {}
}

Categories

Resources