I am trying to print numbers 0,1, 2 and so on using the three different threads in below order by using threadlocal variables :
0- thread 0
1- Thread 1
2- Thread 2
3- thread 0
4- Thread 1
.
.
Below is the code where i am putting an integer in the threadlocal storage and comparing it with the atomic integer which gets incremented by every thread.
public class alternate123
{
public static void main(String as[])
{
Object ob = new Object ();AtomicInteger t = new AtomicInteger(0);
Thread t1 = new Thread ( new printpattern(t,0),"t0");
Thread t2 = new Thread ( new printpattern(t,1),"t1");
Thread t3 = new Thread ( new printpattern(t,2),"t2" );
t1.start();
t2.start();
t3.start();
}
}
class printpattern implements Runnable
{
//Integer t ;
//Object ob = new Object ();
AtomicInteger ai;
private ThreadLocal<Integer> t = new ThreadLocal<Integer>() ;
public printpattern(AtomicInteger at,Integer i)
{
//
ai=at;
t.set(i);
}
#Override
public void run()
{
// TODO Auto-generated method stub
synchronized (ai) {
while (true)
{if (ai.get()%3==
t.get()) // ----------------------- null pointer exception here
{
try {
ai.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
try {
Thread.sleep(300);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Current thread id "+Thread.currentThread().getName()+"value of integer is "+ai.get());;
ai.incrementAndGet();
ai.notify();
}
}
}
}
i am getting null while trying to do t.get() and below is the stacktrace :
Exception in thread "t2" java.lang.NullPointerException
at printpattern.run(alternate123.java:46)
at java.lang.Thread.run(Thread.java:619)
Exception in thread "t0" java.lang.NullPointerException
at printpattern.run(alternate123.java:46)
at java.lang.Thread.run(Thread.java:619)
Exception in thread "t1" java.lang.NullPointerException
at printpattern.run(alternate123.java:46)
at java.lang.Thread.run(Thread.java:619)
i am setting threadlocal variable using set method which i doubt is erroneous . Please let me know what could be the issue .
The constructor is called in your main thread, so the value is set for that thread: you have to set the threadlocal value in the run method. Just store the integer value (i param in your constructor) as a field inside printpattern class and then call t.set(i) in the run method.
P.S.: please rename printpattern to PrintPattern - it's a class.
Calling the set method will only assign the value for the current thread. You are setting the value from your main thread. So it will only be available from your main thread.
Actually, you only need 1 instance of a ThreadLocal in this case, then you can reuse it for multiple threads. But either way, it is crucial that you set the value from within the individual threads. (i.e. in your run method)
You could see a ThreadLocal<Integer> object as a Map<Thread, Integer> in a way, where the set method is equivalent to map.put(Thread.currentThread(), value). That's not really how it works internally, but from a functional point of view, that's pretty much what it does.
Here's an example that reuses the threadlocal for multiple threads. (Changes are marked with //CHANGE x comments.)
public class Alternate123 {
public static void main(String as[]) {
// CHANGE 1: create only 1 threadlocal instance.
ThreadLocal<Integer> threadLocal = new ThreadLocal<Integer>();
// CHANGE 2: pass the threadlocal to the individual threads.
Thread t1 = new Thread(new printpattern(0, threadLocal), "t0");
Thread t2 = new Thread(new printpattern(1, threadLocal), "t1");
Thread t3 = new Thread(new printpattern(2, threadLocal), "t2");
t1.start();
t2.start();
t3.start();
}
}
class printpattern implements Runnable {
// CHANGE 3: keep track of the initial value
Integer startValue;
ThreadLocal<Integer> threadLocal;
AtomicInteger ai = new AtomicInteger();
public printpattern(Integer i, ThreadLocal<Integer> threadLocal) {
// CHANGE 4: don't assign the value to the threadlocal yet.
// Because we are still in the main-thread when we reach this point.
this.startValue = i;
this.threadLocal = threadLocal;
}
#Override
public void run() {
// CHANGE 5: Assign the initial value to the threadlocal
// this time we are doing it from within the individual threads.
if (this.threadLocal.get() == null) {
this.threadLocal.set(startValue);
}
synchronized (ai) {
while (true) {
if (ai.get() % 3 == t.get()) {
try {
ai.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
try {
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
// CHANGE 6: I had to change something here to make it compile. Not really relevant.
System.out.println("Current thread id " + Thread.currentThread().getName() + "value of integer is ...");
ai.incrementAndGet();
ai.notify();
}
}
}
}
Related
Can this code deadlock with thread 1 calling one and thread 2 calling two. That is, can the acquisition of the inner lock be reordered to before the acquisition of the outer one (from the POV of the other thread)?
private final Object foo = new Object();
synchronized void one() {
// ...
synchronized(this.foo) {
// ...
}
// ...
}
synchronized void two() {
// ...
synchronized(this.foo) {
// ...
}
// ...
}
No, this will not deadlock.
When synchronized methods are called the intrinsic lock of this is locked before the method’s body is executed. Here either thread 1 or thread 2 will get to run its method, and the other one will not be able to lock on the intrinsic lock of this.foo so the owner of the lock of this will be able to lock this.foo.
So for with a Simple Test :
class LockTest implements Runnable {
public final Object foo = new Object();
boolean runOne;
public LockTest(boolean runOne) {
this.runOne = runOne;
}
synchronized void one() {
System.out.println("runnin one function");
synchronized(this.foo) {
try {
System.out.println("Enter Sleep function one");
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
synchronized void two() {
System.out.println("running two function");
synchronized(this.foo) {
try {
System.out.println("enter sleep function two");
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
#Override
public void run() {
if(runOne)
one();
else
two();
}
}
With this in a Main class :
while (true)
{
LockTest document2 = new LockTest(true);
LockTest document3 = new LockTest(false);
Thread tread1 = new Thread(document2);
Thread tread2 = new Thread(document3);
tread1.start();
tread2.start();
a++;
if(a==10)
break;
}
We are not locking and even watching with a Thread Dump everything is working Fine. Why? Because every time we are initializating a new Thread with a new object foo. But if that object is declared as static it will be a lock and the others threads need to wait. So from my test and POV. No, it can't be deadlocked.
I am trying to print numbers from 1 to 10 in sequence using a shared integer object across multiple threads. When using the shared object as AtomicInteger, the program works correctly, but when using normal Integer objects, the program throws an exception and I don't know why this is happening.
Program with AtomicInteger
import java.util.concurrent.atomic.AtomicInteger;
public class ThreadingProblem {
public static void main(String[] args) {
AtomicInteger sharedInt = new AtomicInteger(0);
Thread t1 = new Thread(new ThreadingPrintingTask(sharedInt), "PrinterThread");
Thread t2 = new Thread(new ThreadingIncrementingTask(sharedInt), "IncrementerThread");
t1.start();
t2.start();
}
}
class ThreadingPrintingTask implements Runnable {
private AtomicInteger sharedObject;
public ThreadingPrintingTask(AtomicInteger sharedObject) {
this.sharedObject = sharedObject;
}
#Override
public void run() {
try {
synchronized (sharedObject) {
while (true) {
sharedObject.wait();
System.out.println("Shared object value is: " + sharedObject);
sharedObject.notify();
}
}
}
catch (InterruptedException e) {
}
}
}
class ThreadingIncrementingTask implements Runnable {
private AtomicInteger sharedObject;
public ThreadingIncrementingTask(AtomicInteger sharedObject) {
this.sharedObject = sharedObject;
}
#Override
public void run() {
synchronized (sharedObject) {
while (this.sharedObject.get() < 10) {
this.sharedObject.incrementAndGet();
this.sharedObject.notify();
try {
this.sharedObject.wait();
}
catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
Output
Shared object value is: 1
Shared object value is: 2
Shared object value is: 3
Shared object value is: 4
Shared object value is: 5
Shared object value is: 6
Shared object value is: 7
Shared object value is: 8
Shared object value is: 9
Shared object value is: 10
Program with normal Integer object
public class ThreadingProblem {
public static void main(String[] args) {
Integer sharedInt = new Integer(0);
Thread t1 = new Thread(new ThreadingPrintingTask(sharedInt), "PrinterThread");
Thread t2 = new Thread(new ThreadingIncrementingTask(sharedInt), "IncrementerThread");
t1.start();
t2.start();
}
}
class ThreadingPrintingTask implements Runnable {
private Integer sharedObject;
public ThreadingPrintingTask(Integer sharedObject) {
this.sharedObject = sharedObject;
}
#Override
public void run() {
try {
synchronized (sharedObject) {
while (true) {
sharedObject.wait();
System.out.println("Shared object value is: " + sharedObject);
sharedObject.notify();
}
}
}
catch (InterruptedException e) {
}
}
}
class ThreadingIncrementingTask implements Runnable {
private Integer sharedObject;
public ThreadingIncrementingTask(Integer sharedObject) {
this.sharedObject = sharedObject;
}
#Override
public void run() {
synchronized (sharedObject) {
while (this.sharedObject < 10) {
this.sharedObject++;
this.sharedObject.notify();
try {
this.sharedObject.wait();
}
catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
Output
Exception in thread "IncrementerThread" java.lang.IllegalMonitorStateException
at java.lang.Object.notify(Native Method)
at com.itiviti.apps.catalys.shared.mock.ThreadingIncrementingTask.run(ThreadingProblem.java:52)
at java.lang.Thread.run(Unknown Source)
this.sharedObject++; does not do what you assumed it would do.
Since Integer is immutable, it can't change the existing shared object. What this operation does instead is unbox the value into an int, increment it, then box it back into a different Integer instance.
So your code is (almost*) equivalent to the following:
int temp = this.sharedObject.intValue();
temp = temp + 1;
this.sharedObject = new Integer(temp);
As at this point your object is no longer the same instance, your synchronized blocks won't line up with the wait()/notify() calls.
Note that this has got nothing to do with the atomicity of AtomicInteger, it's simply to do with how the ++ operator works on an Integer.
*In reality you might get a cached instance instead of new Integer(), but it will still be a different instance, as it represents a different int value.
I am trying to generate Odd/Even numbers using 2 threads using wait notify.
But It is just printing 1.
Below is the code:
Even.java
public class Even implements Runnable {
private int i; private Object ob
public Even(int i,Object o) {
this.i=i;
this.ob=o;
}
#Override
public void run() {
while (true) {
synchronized (ob) {
while (i % 2 == 0) {
try {
ob.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
i++;
System.out.println(i);
ob.notifyAll();
}
}
}
}
Odd.java
public class Odd implements Runnable {
private int i; private Object ob;
public Odd(int i) {
this.i=i;
this.ob=o;
}
#Override
public void run() {
while (true) {
synchronized (ob) {
while (i % 2 == 1) {
try {
ob.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
i++;
System.out.println(i);
ob.notifyAll();
}
}
}
}
Test.java
public class Test {
public static void main(String[] args) {
int i = 0;
Object lock = new Object();
Thread t1 = new Thread(new Even(i),lock);
Thread t2 = new Thread(new Odd(i),lock);
t1.start();
t2.start();
}
}
Output:
1
Can anyone tell me where I am making the mistake?
Hmm, I would assume that it could be a problem that Integer appears to be immutable in Java. Thus you will not synchronize on the same objects anymore, if one of the two classes changed the i value (which it apparently does since the first output is 1).
So since you change the value stored in i in Odd and call notifyAll on the new object I that Java will complain since you call notifyAll on an object that actually never has been locked.
The threads have fallen into INDEFINITE WAITING state. Note that (t1 i.e instance of Even and t2 i.e instance of Odd), each have a separate copy of instance variable i.
Here is whats going on behind the scenes:
Initially, both thread t1 (Even) and t2 (Odd) are in READY and then RUNNABLE state
Lets assume t1 is scheduled and gets processor to execute. t1 enters RUNNING state. t1's run() is invoked
while(true) succeeds and control enters outer while loop
because of synchronized(ob) t1 locks object ob
since i is 0 initially; i % 2 == 0 condition evaluates to true
control now enters body of inner while loop, then try block and invokes ob.wait();
t1 enters WAITING state and waits until someone notifies on object ob
Now, t2 is scheduled and gets processor to execute. t2 enters RUNNING state
while(true) succeeds and control enters outer while loop
because of synchronized(ob) t2 locks object ob
i is 0 initially (remember the i incremented previously was local to t1 - Even.i). The variable i in this context is local to t2 i.e. Odd.i.
Hence i % 2 == 1 evaluates to false and control skips inner while loop
Control reaches i++; i is incremented from 0 to 1
The statement System.out.println(i); prints 1 to console
contorl moves to next line and ob.notifyAll(); is invoked and all the threads waiting on object ob (t1 in our case) are notified
At this point, both t1 and t2 are back in RUNNABLE state again
Depends on processor which thread to schedule
Lets assume t1 is scheduled and gets processor to execute
t1 resumes its operations from where it left previously (i.e the statement after ob.wait();)
control reaches catch (InterruptedException e) and since there is no exception, its skipped and control comes back to while ( i % 2 == 0) check
Remember, t1's i (i.e Even.i) is still 0 because control din't reach the line i++; in Even class
Hence i % 2 == 0 evaluates to true and control enters into body of while loop, then enters the try block and invokes ob.wait();
t1 enters WAITING state again and waits until someone notifies on object ob
Now, t2 is scheduled and gets processor to execute. t2 enters RUNNING state
t2 resumes its operations from where it left previously (i.e the statement after ob.notifyAll();)
since there is no other statement after ob.notifyAll();, the control reaches outer while loop
while(true) is evaluated and control enters body of outer while loop
because of synchronized(ob) t1 locks object ob
Remember t2's i is now 1 because it was incremented previously and printed on console
Hence, while ( i % 2 == 1) is evaluated to true and control enters body of inner while loop, then try block and invokes ob.wait();
As a result, t2 enters WAITING state
t1 and t2 are both in WAITING state now; waiting on object ob. Waiting for someone to notify them on object ob. Sadly, there is no one to rescue
Hence the INDEFINITE WAITING
Following code should help in what you are trying to achieve
public class EvenOddTest {
public static void main(String[] args) {
Lock lock = new Lock();
Thread t1 = new Thread(new Even(lock));
Thread t2 = new Thread(new Odd(lock));
t1.start();
t2.start();
}
}
class Lock {
private int data;
public void increment() {
data++;
}
public int getData() {
return data;
}
}
class Even implements Runnable {
private Lock ob;
public Even(Lock o) {
this.ob = o;
}
#Override
public void run() {
while (true) {
synchronized (ob) {
while (ob.getData() % 2 == 0) {
try {
ob.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
ob.increment();
System.out.println(ob.getData());
ob.notifyAll();
}
}
}
}
class Odd implements Runnable {
private Lock ob;
public Odd(Lock o) {
this.ob = o;
}
#Override
public void run() {
while (true) {
synchronized (ob) {
while (ob.getData() % 2 == 1) {
try {
ob.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
ob.increment();
System.out.println(ob.getData());
ob.notifyAll();
}
}
}
}
Note:
I have refactored your code so that the object on which threads try to obtain lock and wait upon, holds the data as well.
lock object is now the shared instance between Even and Odd threads.
With my previous reasoning, the code should be self explanatory.
This is not actual way of doing things in parallel computing, to leverage multi-threading power/capabilities. However, it should be a good starter exercise.
You can put i variable as a class attribute in Test class, then create an object of type Test and pass it as parameter to the constructors:
public class Test {
public Integer i = 0;
public static void main(String[] args) {
Object o = new Object();
Test t = new Test();
Thread t1 = new Thread(new Even(t,o));
Thread t2 = new Thread(new Odd(t,o));
t1.start();
t2.start();
}
}
public class Even implements Runnable {
private Test t;
private Object o;
public Even(Test t, Object o) {
this.t=t;
this.o=o;
}
#Override
public void run() {
while (true) {
synchronized (o) {
while (t.i % 2 == 0) {
try {
o.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
t.i++;
System.out.println(t.i);
o.notifyAll();
}
}
}
}
public class Odd implements Runnable {
private Test t;
private Object o;
public Odd(Test t, Object o) {
this.t=t;
this.o = o;
}
#Override
public void run() {
while (true) {
synchronized (o) {
while (t.i % 2 == 1) {
try {
o.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
t.i++;
System.out.println(t.i);
o.notifyAll();
}
}
}
}
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.
public class ObjectLevelLock implements Runnable{
int count = 0;
int uncount = 10;
public static Object lock = new Object();
public static Object lock1 = new Object();
public void counter(){
synchronized (lock) {
for(int i = 0; i<10; i++){
System.out.println(Thread.currentThread().getName()+"------"+count++);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// decrem();
}
}
}
public void decrem(){
synchronized(lock1){
for(int i =10; i>0; i-- ){
System.out.println(Thread.currentThread().getName()+"------"+uncount--);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
public void xxx(){
while(true){
decrem();
counter();
}
}
public void run(){
xxx();
}
public static void main(String[] args) {
ObjectLevelLock obj1 = new ObjectLevelLock();
ObjectLevelLock obj2 = new ObjectLevelLock();
Thread t1 = new Thread(obj1,"Thread 1");
Thread t2 = new Thread(obj2,"Thread 2");
t1.start();
t2.start();
}
}
On executing this program ,I get the following output at some point :
Thread 1------0
Thread 2------0
Thread 1-------1
Thread 2------1
Thread 1-------2
Thread 2------2
Thread 1-------3
Thread 2------3
Thread 1-------4
Thread 2------4
Thread 1-------5
Thread 2------5
Thread 2------6
Thread 1-------6
Thread 2------7
Thread 1-------7
Thread 1-------8
Thread 2------8
Thread 1-------9
As can be seen from output ,both threads are accessing the same method that's why both are incrementing count variable .Please let me know how is that possible ,if I am using static third party locks like
public static Object lock = new Object();
static means lock is acquired on the class which means is should be accessible by only one thread at a time.But then why then output trace showing both threads are in the same method and executing it concurrently.
Output should be :
One thread incrementing count variable other thread should be decrementing uncount variable and these two operation can also happen concurrently