Calling method of blocked thread - java

I'm just starting to learn about multithreading in Java, and am still figuring some things out. Firstly, can a class that extends Thread have other instance methods associated with it that can be called during its execution---and if so, can it change the state of the thread during its execution? Secondly, if this class is blocked waiting for a semaphore, can its instance methods still be called? Something like having these 2 threads run:
Thread1 t;
public class Thread1 extends Thread {
private int num;
public run() {
sem.acquire(); // here it blocks waiting for another thread
//to call its setInt function and release it
System.out.println("num is " + num);
}
public void setInt(int i) {
num = i;
}
}
public class Thread2 extends Thread {
public run() {
t.setInt(5);
sem.release();
}
}

There is some confusion here.
Threads don't have methods. Classes have methods.
Classes aren't blocked. Threads are blocked.
You can call any method any time. The method itself may be synchronised, which will delay entry to it, or it may used synchronization internally, ditto, or semaphores, ditto.

To demonstrate what you are looking for, here is the a code example wich I tested:
package test2;
import java.util.concurrent.Semaphore;
public class mainclass {
static Thread1 t;
static Semaphore sem;
static Semaphore sem_protect;
public synchronized static void main (String[] args) {
sem = new Semaphore(0);
sem_protect = new Semaphore(1);
t = new Thread1();
Thread1 th1 = new Thread1();
th1.start();
Thread2 th2 = new Thread2();
th2.start();
try {
synchronized (th2){
th2.wait();
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("The end !");
}
public static class Thread1 extends Thread {
private int num;
public void run() {
try {
sem.acquire();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} // here it blocks waiting for another thread
//to call its setInt function and release it
try {
sem_protect.acquire();
System.out.println("num is " + num);
sem_protect.release();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public synchronized void setInt(int i) {
try {
sem_protect.acquire();
this.num = i;
sem_protect.release();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("value of num is: "+num);
}
}
public static class Thread2 extends Thread {
public void run() {
t.setInt(5);
sem.release();
}
}
}
Here is the result of execution of this code:
value of num is: 5
The end !
num is 0
With this result you can see that you can still access the methods of the class thread1 from the Thread2 . It means you access the method of the class instance, there is no method for a thread. (this is an answer for your first question)
The state of first thread is not changed by the second, num is still 0 for the first thread, the threads have each their own context.
even if we protect the access to num with another semaphore we dont have the same num value for the two threads.

Related

Unexpected behaviour of Threads

I am trying to achieve that thread2 should complete first, then thread1, For this O am using join() method. But if I uncomment the System.out.println() present in the try block of thread1 class. then
code give null pointer exception. Why in try block I need to add line, it doesn't make any sense that adding a line code start working.
Demo class
public class Demo {
public static void main(String[] args) throws InterruptedException {
Thread1 t1 = new Thread1();
Thread2 t2 = new Thread2();
t1.start();
t2.start();
System.out.println("main Thread");
Thread.sleep(10);
}
}
Thread1 class
public class Thread1 extends Thread {
#Override
public void run() {
try {
// System.out.println(); // on adding anyline, this whole code works!!, uncommenting this line of code give NPE
Thread2.fetcher.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
for (int i = 0; i < 5; i++) {
System.out.println("in thread1 class, Thread-1 ");
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Thread2 class
public class Thread2 extends Thread {
static Thread fetcher;
#Override
public void run() {
fetcher= Thread.currentThread(); // got the thread2
for (int i = 0; i < 5; i++) {
System.out.println("in thread2 class, Thread-2");
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
OUTPUT of the program
in thread2 class Thread-2
Exception in thread "Thread-0" java.lang.NullPointerException
at org.tryout.Thread1.run(Thread1.java:22)
in thread2 class Thread-2
in thread2 class Thread-2
in thread2 class Thread-2
in thread2 class Thread-2
It is working purely by "pure luck" the
System.out.println();
internally calls synchronized, which is working as a delay that gives enough time for Thread 2 its field fetcher in:
fetcher= Thread.currentThread(); // got the thread2
In order to avoid this race-condition you need to ensure that the Thread 2 sets the field fetcher before Thread 1 accesses it. For that you case use, among others, a CyclicBarrier.
??A synchronization aid that allows a set of threads to all wait for
each other to reach a common barrier point.** CyclicBarriers are useful
in programs involving a fixed sized party of threads that must
occasionally wait for each other. The barrier is called cyclic because
it can be re-used after the waiting threads are released.
First, create a barrier for the number of threads that will be calling it, namely 2 threads:
CyclicBarrier barrier = new CyclicBarrier(2);
With the CyclicBarrier you can then force Thread 1 to wait for Thread 2 before accessing its field fetcher:
try {
barrier.await(); // Let us wait for Thread 2.
Thread2.fetcher.join();
} catch (InterruptedException | BrokenBarrierException e) {
// Do something
}
Thread 2 also calls the barrier after having setting up the field fetcher, accordingly:
fetcher = Thread.currentThread(); // got the thread2
try {
barrier.await();
} catch (InterruptedException | BrokenBarrierException e) {
e.printStackTrace();
}
Both threads will continue their work as soon as both have called the barrier.
An example:
public class Demo {
public static void main(String[] args) throws InterruptedException {
CyclicBarrier barrier = new CyclicBarrier(2);
Thread1 t1 = new Thread1(barrier);
Thread2 t2 = new Thread2(barrier);
t1.start();
t2.start();
System.out.println("main Thread");
Thread.sleep(10);
}
}
public class Thread1 extends Thread {
final CyclicBarrier barrier;
public Thread1(CyclicBarrier barrier){
this.barrier = barrier;
}
#Override
public void run() {
try {
barrier.await();
Thread2.fetcher.join();
} catch (InterruptedException | BrokenBarrierException e) {
// Do something
}
for (int i = 0; i < 5; i++) {
System.out.println("in thread1 class, Thread-1 ");
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class Thread2 extends Thread {
static Thread fetcher;
final CyclicBarrier barrier;
public Thread2(CyclicBarrier barrier){
this.barrier = barrier;
}
#Override
public void run() {
fetcher = Thread.currentThread(); // got the thread2
try {
barrier.await();
} catch (InterruptedException | BrokenBarrierException e) {
e.printStackTrace();
}
for (int i = 0; i < 5; i++) {
System.out.println("in thread2 class, Thread-2");
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
If your code is not for education purposes, and you are not force to use any particular synchronization mechanism for learning purposes. In the current context you can simply pass the thread 2 as parameter of the thread 1, and call join directly on it as follows:
public class Demo {
public static void main(String[] args) throws InterruptedException {
Thread2 t2 = new Thread2();
Thread1 t1 = new Thread1(t2);
t1.start();
t2.start();
System.out.println("main Thread");
Thread.sleep(10);
}
}
public class Thread1 extends Thread {
final Thread thread2;
public Thread1(Thread thread2){
this.thread2 = thread2;
}
#Override
public void run() {
try {
thread2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
for (int i = 0; i < 5; i++) {
System.out.println("in thread1 class, Thread-1 ");
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class Thread2 extends Thread {
#Override
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println("in thread2 class, Thread-2");
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
This should allow your code to work properly. There is insufficient time between thread startups to allow fletcher to initialize.
try {
Thread.sleep(500);
Thread2.fetcher.join();
} catch (InterruptedException ie) {
}
For something this simple, the sleep should work. But for more complicated threads, appropriate synchronization is the key. And you should be aware that thread programming can be one of the most difficult aspects of programming to debug.

Printing Two Different Strings in two Threads in Order

I am trying to Write a Program where two threads are running simultaneously. One is printings Jack and other is Jones. The expected output is :
Jack Jones Jack Jones and so on. But I am facing issue while doing calling notifyAll(). Can anyone tell me what is the problem ?
Exception
Starting thread
Jack Jones Exception in thread "Thread-0" Exception in thread "Thread-1" java.lang.IllegalMonitorStateException
at java.lang.Object.notifyAll(Native Method)
at JonesThread.printJones(JonesThread.java:32)
at JonesThread.run(JonesThread.java:14)
java.lang.IllegalMonitorStateException
at java.lang.Object.notifyAll(Native Method)
at JackThread.printJack(JackThread.java:36)
at JackThread.run(JackThread.java:15)
Jack Thread
import java.util.concurrent.atomic.AtomicBoolean;
public class JackThread extends Thread {
AtomicBoolean i;
public JackThread(AtomicBoolean i2) {
this.i = i2;
}
public void run() {
while (true) {
try {
printJack();
Thread.sleep(10000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
private void printJack() throws InterruptedException {
synchronized (i) {
while (i.get()) {
{
wait();
}
}
System.out.print("Jack ");
i.set(true);
notifyAll();
}
}
}
Jones Thread
import java.util.concurrent.atomic.AtomicBoolean;
public class JonesThread extends Thread {
AtomicBoolean i;
public JonesThread(AtomicBoolean i2) {
this.i = i2;
}
public void run() {
while (true) {
try {
printJones();
Thread.sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
private void printJones() throws InterruptedException {
synchronized (i) {
while (!i.get()) {
wait();
}
System.out.print("Jones ");
i.set(false);
notifyAll();
}
}
}
MainProgram
import java.util.concurrent.atomic.AtomicBoolean;
public class ThreadMain {
public static void main(String args[]) {
AtomicBoolean i = new AtomicBoolean(false);
System.out.println("Starting thread");
JackThread t1 = new JackThread( i); // Will give chance to Print Jack first
JonesThread t2 = new JonesThread(i);// Jones will follow Jack
t1.start();
t2.start();
}
}
The definition of wait is that if you say
someObject.wait();
the thread will wait until somebody notifies someObject's monitor. Another thread can do that by calling
someObject.notify(); // or notifyAll
The thing is, though, the threads have to coordinate by using the same object. You haven't specified an object, so your wait() is equivalent to
this.wait();
That is, the JackThread object is waiting for somebody to notify itself. But nobody is notifying the JackThread object. When your JonesThread calls notifyAll(), it's the same as
this.notifyAll();
so it's notifying itself, i.e. a JonesThread object. So basically, your two threads are talking to themselves and not to each other.
It looks like you've set up i as an object that is known to both threads, so you could use that for your wait and notify, i.e. i.wait(), i.notifyAll(). Disclaimer: I haven't tested it.

Having troubles with threads and semaphors in JAVA

I am new to threading and semaphors, and I have some problem in synchronizing threads. For example, in the following code I want to do a pretty simple thing. To let one thread run, while other waits. For example, if it starts with the first thread, I want the second to wait for the first one to finish and then start. I really don't know what am I doing wrong.
Here is the code :
import java.io.*;
import java.util.concurrent.Semaphore;
public class ThreadTest {
public static void main(String[] args) throws InterruptedException {
Semaphore binaren = new Semaphore(1);
Runnable t1 = new T2(binaren);
Thread a = new Thread(t1);
Thread a2 = new T1(binaren);
System.out.println(binaren.availablePermits());
a.start();
a2.start();
}
}
class Work {
private static int a = 4;
public synchronized static void QQR(String s1)
{
for(int i=0;i<100;i++)
System.out.println(s1+" : "+(a++));
}
}
class T1 extends Thread
{
Semaphore sem;
public T1(Semaphore s1)
{
sem=s1;
}
public void run()
{
synchronized(this) {
if(!sem.tryAcquire()){
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Work.QQR("T1");
sem.release();
notifyAll();
}
}
}
class T2 extends Thread
{
Semaphore sem;
public T2(Semaphore s1)
{
sem=s1;
}
#Override
public void run() {
synchronized(this) {
if(!sem.tryAcquire()){
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Work.QQR("T2");
sem.release();
notifyAll();
}
}
}
The problem is that notify and notifyAll only wake up threads holding locks on the monitor being notified. But the t1 and t2 instances are waiting on themselves and are never awoken. You can have them wait on the semaphore for this simple test or introduce a new shared object to see how it works.
Use
sem.wait();
and
sem.notifyAll();
You can use Thread.join() on the first thread so that second thread will wait till the execution of this instance is not completed.

Notify not getting the thread out of wait state

I am trying to use 2 threads. 1 thread prints only odd number and the other thread prints only even number and It has to be an alternative operation.
Eg:
Thread1 1
Thread2 2
Thread1 3
Thread2 4
and so on..
Below is the program, please let me know where I am going wrong as the thread1 is not coming out of wait state even when the thread2 is notifying it..
public class ThreadInteraction {
public static void main(String[] args) {
new ThreadInteraction().test();
}
private void test() {
ThreadA ta = new ThreadA();
Thread t = new Thread(ta);
t.start();
try {
Thread.sleep(1000);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
for(int i=2;i<=50;){
System.out.println("Thread2 "+i);
synchronized (t) {
try {
t.notify();
t.wait();
} catch (Exception e) {
e.printStackTrace();
}
}
i=i+2;
}
}
}
class ThreadA implements Runnable{
#Override
public void run() {
for(int i=1;i<50;){
System.out.println("Thread1 "+i);
synchronized (this) {
try {
notify();
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
i=i+2;
}
}
}
Problem is that in one case you are taking lock on Thread t [synchronized (t) ] while in other case you are taking lock on TheadA object itself [synchronized(this)].
If you want threads to talk to each other then both should take lock on same object only then wait notify will work as you expect.
Edit:
There is another problem in your program, you are not using any variable to coordinate between 2 threads. SO you may see output like this 2,1,4,3...so on. Point is threads will work alternately but not in sequence.
So you should share a single variable between 2 threads which should be incremented.
Second issue is you are not taking care of spurious wake up calls [read some docs on this], you should always have wait called inside a while loop.
Modified my code based on the answer provided by Lokesh
public class ThreadInteraction {
public static void main(String[] args) {
new ThreadInteraction().test();
}
private void test() {
ThreadA ta = new ThreadA();
Thread t = new Thread(ta);
t.start();
try {
Thread.sleep(1000);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
for(int i=2;i<=50;){
System.out.println("Thread2 "+i);
synchronized (ta) {
try {
ta.notify();
ta.wait();
} catch (Exception e) {
e.printStackTrace();
}
}
i=i+2;
}
}
}
class ThreadA implements Runnable{
#Override
public void run() {
for(int i=1;i<50;){
System.out.println("Thread1 "+i);
synchronized (this) {
try {
notify();
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
i=i+2;
}
}
}
You have a real confusion of threads and locks. I suggest you create one and only one object to use for locking to start with as you don't appear to have a clear idea what you are locking.
If you notify() and nothing is listening, the signal is lost. However, a wait() can wake spuriously.
For this reason, a notify() should be accompanied by a state change and a wait() should be in a loop checking that change.

What if I am waiting on an object which is not Runnable?

Consider the following code :-
public class UsingWait1{
public static void main(String... aaa){
CalculateSeries r = new CalculateSeries();
Thread t = new Thread(r);
t.start();
synchronized(r){
try{
r.wait(); //Here I am waiting on an object which is Runnable. So from its run method, it can notify me (from inside a synchronized block).
} catch (InterruptedException e) {
System.out.println("Interrupted");
}
}
System.out.println(r.total);
try{
Thread.sleep(1);
} catch (InterruptedException e){
System.out.println("Interrupted");
}
System.out.println(r.total);
}
}
class CalculateSeries implements Runnable{
int total;
public void run(){
synchronized(this){
for(int i = 1; i <= 10000; i++){
total += i;
}
notify(); // Line 1 .. Notify Exactly one of all the threads waiting on this instance of the class to wake up
}
}
}
Here I am waiting on CalculateSeries which is Runnable. So I can notify the waiting thread from the run() method of CalculateSeries.
But now, consider the following code where I am waiting on an object which is not Runnable.
public class WaitNotOnThread{
public static void main(String... aaa){
NotRunnable nr = new NotRunnable();
IAmRunnable r = new IAmRunnable(nr);
new Thread(r).start();
synchronized(nr){
try{
nr.wait();
} catch(InterruptedException e){
System.out.println("Wait interrupted");
}
System.out.println("After being notified within synchronized");
}
System.out.println("After synchronized");
}
}
class IAmRunnable implements Runnable{
NotRunnable nr;
IAmRunnable(NotRunnable nr){
this.nr = nr;
}
public void run(){
synchronized(nr){
try{
Thread.sleep(1000);
} catch(InterruptedException e){
System.out.println("Sleeping Interrupted :( ");
}
notify(); // Line 2
}
}
}
class NotRunnable{
}
Here I get an IllegalMonitorStateException at Line 2. I am waiting on the same instance of the object (which is not Runnable) while calling both, wait() as well as notify(). Then what is the problem?
Can someone also give some scenarios where it would be useful to wait on an object which is not Runnable??
Wait need not be on Runnable. That is why notify() is on Object and not on Runnable. I guess that helps in all cases we want to avoid busy wait.
The problem seems to be the synchronized() is on nr, and the notify is called on different object. Also synchronized should be on final variables.
class IAmRunnable implements Runnable {
final NotRunnable nr;
IAmRunnable( final NotRunnable nr) {
this.nr = nr;
}
public void run() {
synchronized (nr) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
System.out.println("Sleeping Interrupted :( ");
}
nr.notify(); // Line 2
}
}
}

Categories