Running multiple instance of Thread Object - java

I have a Thread Object - ThreadB which add numbers 1 - 100. I create 2 instances of it - b & c.
Start the 2 threads(different instances) and run it.
Result:
Waiting for b to complete...
Total is: 4950
Waiting for c to complete...
Why does my second instance does not complete...
Java code:
public class ThreadA {
public static void main(String[] args){
ThreadB b = new ThreadB();
ThreadB c = new ThreadB();
b.start();
c.start();
synchronized(b){
try{
System.out.println("Waiting for b to complete...");
b.wait();
}catch(InterruptedException e){
e.printStackTrace();
}
System.out.println("Total is: " + b.total);
}
synchronized(c){
try{
System.out.println("Waiting for c to complete...");
c.wait();
}catch(InterruptedException e){
e.printStackTrace();
}
System.out.println("Total is: " + c.total);
}
}
}
class ThreadB extends Thread{
int total;
#Override
public void run(){
synchronized(this){
for(int i=0; i<100 ; i++){
total += i;
}
notify();
}
}
}

Because your second ThreadB finishes while you're in the block synchronized on the first ThreadB. You then wait on your second ThreadB, but the notify() has already happened so you'll wait there forever.
Note that this isn't guaranteed, and your program will probably work sometimes.
Put some print statements inside your ThreadB class to test this theory.

If you just wish to wait for both threads to complete you should use the Thread join method, which is specifically designed for this.
It also makes use of wait and notify (or rather notifyAll) underneath the hood.
Your code will be much cleaner too:
System.out.println("Waiting for b to complete...");
b.join();
System.out.println("b completed.");
System.out.println("Waiting for c to complete...");
c.join();
System.out.println("c completed.");
System.out.println("b's total is " + b.total");
System.out.println("c's total is " + c.total");

This is not the right way to approach the problem. You are trying to serialize two independent threads, which is pointless.
If your only purpose is to give the user some feedback, you make each thread inform the user that it terminated its job before quitting:
class ThreadB extends Thread{
String name;
int total;
public ThreadB(String name){
this.name = name;
}
#Override
public void run(){
System.out.println("Waiting for "+name+" to complete...");
for(int i=0; i<100 ; i++){
total += i;
}
System.out.println(name+" completed. Total is "+total);
}
}
public class ThreadA {
public static void main(String[] args){
ThreadB b = new ThreadB("b");
ThreadB c = new ThreadB("c");
b.start();
c.start();
}
}
Otherwise, if you need to do something after all threads have finished, you synchronize on a shared object, not on a thread.

Related

Integer value not getting refreshed

I am trying to print even and odd using two separate threads which communicate with each other by wait and notify.
I do know that i refers to Integer object which is in heap. hence changes made by one thread should be visible to both thread. Also I am using volatile keyword for declaration of Integet i.
I cant seem to understand how value of variable i is shown as 1 even after it has been incremented.
The output of code is
Even Thread got lock i=1
Even Thread waiting.. i=1
Odd Thread got lock i=1
Odd Thread : i=2
Odd Thread Run called NotifyAll
Odd Thread got lock i=2
Odd Thread waiting.. i=2
Even Thread woken up.. i=1
Even Thread waiting.. i=1
package programs;
public class EvenOdd {
static Object lck = new Object();
volatile static Integer i=1;
volatile static Integer N = 1000;
public static void main(String args[]){
EvenRunner e = new EvenRunner(lck, i, N);
OddRunner o = new OddRunner(lck, i, N);
Thread t1 = new Thread(e,"Even Thread ");
Thread t2 = new Thread(o,"Odd Thread ");
t1.start();
t2.start();
try {
t1.join();
t2.join();
}catch(InterruptedException ex) {
System.out.println("Interrupted : "+ex);
}
}
}
class EvenRunner implements Runnable{
Object lck;
Integer i;
Integer N;
EvenRunner(Object lck,Integer i,Integer N){
this.lck=lck;
this.i=i;
this.N=N;
}
#Override
public void run() {
while(i<N) {
synchronized(lck) {
System.out.println(" Even Thread got lock i="+i);
while(i%2==1){
try {
System.out.println(" Even Thread waiting.. i="+i);
lck.wait();
System.out.println(" Even Thread woken up.. i="+i);
}catch(InterruptedException e) {
System.out.println("Interrupted thread : "+e);
}
}
++i;
System.out.println(Thread.currentThread().getName()+" : i="+i);
System.out.println(" Even Thread Run called NotifyAll");
lck.notifyAll();
}
}
}
}
class OddRunner implements Runnable{
Object lck;
Integer i;
Integer N;
OddRunner(Object lck,Integer i,Integer N){
this.lck=lck;
this.i=i;
this.N=N;
}
#Override
public void run() {
while(i<N) {
synchronized(lck) {
System.out.println(" Odd Thread got lock i="+i);
while(i%2==0){
try {
System.out.println(" Odd Thread waiting.. i="+i);
lck.wait();
System.out.println(" Odd Thread woken up.. i="+i);
}catch(InterruptedException e) {
System.out.println("Interrupted thread : "+e);
}
}
++i;
System.out.println(Thread.currentThread().getName()+" : i="+i);
System.out.println(" Odd Thread Run called NotifyAll");
lck.notifyAll();
}
}
}
}
Expected Result: should be that other thread should also see the value of variable I as 2 after it has been incremented.
Actual result: value of variable i is read as 1 by other thread even after incrementing it.
Expected output should be that other thread should also see the value of variable I as 2 after it has been incremented.
When you construct evenRunner and oddRunner, you're copying the same Integer reference into each class as an instance field.
But Integer is immutable - when you execute ++i; that changes the field to refer to a different Integer object. It doesn't modify the content of the existing integer object... so your two threads are operating on entirely separate fields, and won't interact at all.
If you want to have a single object that both threads can modify, use AtomicInteger instead.

Control amount of threads reading a file in java (only using synchronized, wait, notify and sleep)

In the problem I am trying to solve, each thread has to read the whole file, (maybe each thread will deliver its content to another task or any other purpose). After reading it, the thread should sleep a bit then try to read the file again, and only a given number(n) of threads should read the file. My attempt to solve this dealing with controling the amount of threads working is in the code below :
import java.util.*;
class Reader implements Runnable{
Thread t;
Controler c;
public Reader(Controler c){
t = new Thread(this);
this.c = c;
t.start();
}
public void run(){
Random ran = new Random();
int napTime;
while(true){
try{
w.intentarLeerArchivo(t);
//Specification says that each reader
//should wait a bit before trying to
//read the file again
napTime = ran.nextInt(1000);
t.sleep(napTime);
}catch(InterruptedException e){
System.out.println("InterruptedException");
}
}
}
}
class Controler{
Random ran;
LinkedList <Reader> readers;
int n;
int count;
public Controler(int n){
readers = new LinkedList <Reader>();
this.n = n;
count = 0;
ran = new Random();
}
public synchronized void getPermission(){
try{
while(count >= n){
wait();
}
notify();
}catch(InterruptedException e){
System.out.println("InterruptedException");
}
}
public synchronized void increaseCount(){
count++;
}
public synchronized void decreaseCount(){
count--;
System.out.println("There are " + count + " threads reading");
}
public void intentarLeerArchivo(Thread t){
int readTime = 1000;
try{
getPermission();
System.out.println("Thread " + t.getId() +" empezó a leer");
increaseCount();
t.sleep(readTime);
System.out.println("Thread " + t.getId() +" is reading");
System.out.println("Thread " + t.getId() + " finished reading");
decreaseCount();
} catch(InterruptedException e){
System.out.println("InterruptedException");
}
}
}
class Initializer{
int numReaders;
int maxReaders;
public Initializer(int numReaders, int maxReaders){
this.numReaders = numReaders;
this.maxReaders = maxReaders;
}
public void init(){
Controler c = new Controler(maxReaders);
for(int i = 0; i < numReaders; i++){
new Reader(c);
}
}
}
public class FileShare{
public static void main(String [] args){
Initializer c = new Initializer(100, 50);
c.init();
}
}
There are a few lines I wrote in order to debug. They print the state of each thread and the number of threads that are reading whenever one of them ends reading. But when I run the program, it turns out that suddenly there are more Threads reading the file than the ones there were supposed to be doing so. I guess it has something to do with my synchronization manipulation. What am I doing wrong?
When a thread is in the
while(...){wait()}
section of your implementation, it wait until someone notify it to go on. Right now, when you finish waiting, you notify right away.
Think about it, if once I get in I notify someone to come, he will not wait until I'm done before coming in. You want to use notify when you leave the file.

Java program freezes when using wait and notifyAll

I'm trying to get into the nitty gritty of understanding how wait and notifyAll work and have hit a roadblock.
This program downloads a long text document, starts multiple threads to count characters and then outputs the count totals.
I'm using wait and notifyAll to control the thread execution so that they are completed in alphabetical order. Here's the code. I'll follow with an explanation of the problem.
public class Test {
public static void main(String[] args) {
//code that reads in the data
LongTask a = new LongTask(buffer, 'a', "Thread_a", 0);
a.start();
LongTask b = new LongTask(buffer, 'b', "Thread_b", 1);
b.start();
//Repeat code for all other characters
a.join();
System.out.println("Alphabet count is: " + SharedResults.getResults());
LongTask class contains constructor and run()
public class LongTask extends Thread {
//Instance variables created here
//LongTask constructor
public LongTask (StringBuffer buffer, char target, String name, int turn)
{
super(name);
this.sharedData = sharedData;
inputData = buffer;
this.target = target;
this.turn = turn;
}
//Run method iterates through input data and counts matching characters,
//then calls addToResults
public synchronized void run()
{
//Thread t = Thread.currentThread();
String name = this.getName();
int runTurn = this.turn;
System.out.println(name + " running - Turn " + runTurn);
Integer count = 0;
for (int i = 0; i < inputData.length(); i++) {
if (inputData.charAt(i) == target) {
count ++;
}
}
ResultsEntry newResult = new ResultsEntry(count, target);
SharedResults.addToResults(newResult, turn);
}
}
SharedResults class adds results to Array. addToResults method performs this action and controls the synchronization.
public class SharedResults extends Thread{
//Code that creates array
//Code for SharedResults constructor
public synchronized static void addToResults(ResultsEntry newResult, int turn)
{
Integer resultsCount = newResult.getCount();
char resultsTarget = newResult.getTarget();
Thread t = Thread.currentThread();
/*
* Turn number is compared to the size of the results array to control the
* order of execution.
*/
while (turn != results.size()){
try {
System.out.println("Wait printout");
t.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(t.getName() + " is adding " + newResult);
SharedResults input = new SharedResults(resultsCount, resultsTarget);
System.out.println("Cumulative Results are " + results);
t.notifyAll();
}
Here's what I'm seeing when I watch this step through in Debug.
-Input executes and all LongTask threads start
(Thread_a should be the first thread to execute addToResults)
-Some threads (not Thread_a) hit the while evaluation of addToResults and do not proceed
-Thread_a hits the while evaluation and fully executes. (Now it should be Thread_b's turn)
-Thread_e executes the "Wait printout" (just a debugging feature that tells me when a thread is waiting) and then the program hangs.
It looks to me like I haven't set up wait correctly. The program actually worked (or appeared to be) correctly until I added in the sysout. Any ideas what's going on here?
To answer my own question,
This was covered in this thread.
The problem is that notifyAll() notify all of that object's threads that are waiting. Because I was calling wait() on each thread, the notifyAll() from another thread wasn't notifying any of the other threads.
As suggested by the linked post, I created a static synchronized object and called the wait and notify methods on that object. The resulting code looked like this:
private static final Object LOCK = new Object();
public static void addToResults(ResultsEntry newResult, int turn)
{
Integer resultsCount = newResult.getCount();
char resultsTarget = newResult.getTarget();
Thread thread = Thread.currentThread();
/*
* Turn number is compared to the size of the results array to control the
* order of execution.
*/
synchronized (LOCK){
while (turn != results.size()){
try {
System.out.println(thread.getName() + " is waiting");
LOCK.wait();
} catch (InterruptedException e) {}
}
System.out.println(thread.getName() + " is adding " + newResult);
SharedResults input = new SharedResults(resultsCount, resultsTarget);
System.out.println("Cumulative Results are " + results);
LOCK.notifyAll();
}
}
Thanks to all who commented!

Unable to understand the behaviour of thread synchronization in following java code

When I execute the following piece of code
public class ThreadTalk {
public static void main(String[] args) {
SimpleThread obj = new SimpleThread();
Thread t = new Thread(obj, "NewThread");
t.start();
synchronized (obj) {
System.out.println("In Synchronized BLOCK");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Out of Synchronized BLOCK");
}
}
}
class SimpleThread implements Runnable {
public void run() {
System.out.println("The thread running now " + Thread.currentThread());
for (int i = 0; i < 10; i++) {
System.out.println("The val of i= " + i);
}
}
}
The output that I am getting is
In Synchronized BLOCK
The thread running now Thread[NewThread,5,main]
The val of i= 0
The val of i= 1
The val of i= 2
The val of i= 3
The val of i= 4
The val of i= 5
The val of i= 6
The val of i= 7
The val of i= 8
The val of i= 9
Out of Synchronized BLOCK
where as I am expecting an output like
In Synchronized BLOCK
Out of Synchronized BLOCK
The thread running now Thread[NewThread,5,main]
The val of i= 0
The val of i= 1
The val of i= 2
The val of i= 3
The val of i= 4
The val of i= 5
The val of i= 6
The val of i= 7
The val of i= 8
The val of i= 9
If I am putting a Lock on the SimpleThread object using the Synchronized block of main thread, how is my NewThread running when main thread is going to sleep.I mean shouldn't the NewThread wait till the Main thread has removed the lock on the SimpleThread object, as both threads are running on the same object.
run() and/or start() do not take any locks. They just run code. You need to actually have SimpleTread take the same lock as the main thread for those two threads to synchronize in some fashion.
Rather than try to synchronize on the the Runnable object, I think best practice would be to explicitly declare a separate object to use as a lock.
class ThreadTalk{
public static void main(String[] args){
Object lock = new Object();
SimpleThread obj=new SimpleThread( lock );
Thread t=new Thread(obj,"NewThread");
t.start();
synchronized(lock){
System.out.println("In Synchronized BLOCK");
try{
Thread.sleep(5000);
}catch(InterruptedException e){
e.printStackTrace();
}
System.out.println("Out of Synchronized BLOCK");
}
}
}
class SimpleThread implements Runnable{
private final Object lock;
public SimpleThread( Object lock ) { this.lock = lock;}
public void run(){
synchronized( lock ) {
System.out.println("The thread running now "+Thread.currentThread());
for(int i=0;i<10;i++){
System.out.println("The val of i= "+i);
}
}
}
}
synchronized block does not do what you think. It means that only one thread can be inside of it (or rather inside any synchronized block on the same object) at the same time. In your case, there is only one (main) thread inside the block. The other one is executing different code. That is expected.
You need to synchronize in both threads on the same object (the so-called "monitor") to make them mutually exclusive.
The simplest way to do that is to make the run() method itself synchronized:
class SimpleThread implements Runnable {
// See the synchronized modifier on the next line
public synchronized void run() {
System.out.println("The thread running now " + Thread.currentThread());
for (int i = 0; i < 10; i++) {
System.out.println("The val of i= " + i);
}
}
}
You would also need to make sure that you synchronize on the SimpleThread object before you start it in a Thread, so you need to move the t.start(); statement inside the synchronized (obj) { block. If you don't do that, the two threads are still improperly synchronized, and there's no telling which thread will run first.

Wait isn't timing out

I made this sample to test wait/notify functionalities:
public class WaitingTest implements Runnable {
Thread b = new Thread(this,"query");
int total=0;
public static void main(String[] args){
WaitingTest w = new WaitingTest();
}
public WaitingTest(){
b.start();
synchronized(b){
try{
System.out.println("Waiting for b to complete...");
b.wait(10);
}catch(InterruptedException e){
e.printStackTrace();
}
System.out.println("Total is: " + total);
}
}
#Override
public void run(){
synchronized(b){
for(int i=0; i<1000000000 ; i++){
total += i;
}
}
}
}
The problem is, my output should be zero since Im notifying the wait after 10ms and my thread takes longer than this to execute its work. So, my output should be zero, instead its coming another value. What am I missing?
EDIT:
public class WaitingTest implements Runnable {
Thread b = new Thread(this,"query");
int total=0;
public static void main(String[] args){
WaitingTest w = new WaitingTest();
}
public WaitingTest(){
b.start();
synchronized(b){
try{
System.out.println("Waiting for b to complete...");
b.wait();
}catch(InterruptedException e){
e.printStackTrace();
}
System.out.println("Total is: " + total);
}
}
#Override
public void run(){
synchronized(b){
b.notify();
for(long i=0; i<100000 ; i++){
total += i;
}
}
}
}
The javadoc for wait() states
This method causes the current thread (call it T) to place itself in
the wait set for this object and then to relinquish any and all
synchronization claims on this object
So when you do
b.wait(10);
the current thread releases the synchronized it has on b and your other thread can therefore acquire it in the run() method coming from
b.start();
The total starts increasing. When 10ms is up, the main thread reacquires the lock on b (assuming the run() completes) and prints out the total. Note that your total will most likely overflow.
You get overflow (you cannot sum up these 1000000000 non-negative ints and store the result in an int). Define total as long. Also call b.notify() or b.notifyAll() after your loop in the run method is done.
Also, change wait(10) to just wait(), this will make the printing thread wait for
the calculating thread as much as needed (and not just for 10 milliseconds).
This is the proper way of doing this test.
Regarding the thread syncing part I suggest you read something e.g. these old articles.
http://www.javaworld.com/article/2074217/java-concurrency/java-101--understanding-java-threads--part-1--introducing-threads-and-runnables.html
http://www.javaworld.com/article/2074318/java-concurrency/java-101--understanding-java-threads--part-2--thread-synchronization.html
http://www.javaworld.com/article/2071214/java-concurrency/java-101--understanding-java-threads--part-3--thread-scheduling-and-wait-notify.html
http://www.javaworld.com/article/2074481/java-concurrency/java-101--understanding-java-threads--part-4---thread-groups--volatility--and-threa.html

Categories