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
Related
I want to display this two threads alternatively like that :
Thread 1
Thread 0
Thread 1
Thread 0
...
That's the basic code from where I started, I tried with wait() notify() Methods but I couldn't get the result wanted.
class Task extends Thread {
#Override
public void run() {
try {
for(int i = 0; i<10; i++){
double dure = Math.random()*200 ;
sleep((long) dure);
System.out.println(Thread.currentThread().getName());
}
} catch (Exception e) {
}
}
}
public class App {
public static void main(String[] args) {
Task t1 = new Task() ;
Task t2 = new Task() ;
t1.start();
t2.start();
try {
t1.join();
t2.join();
} catch (InterruptedException e) {
}
}
} ```
I see two solutions:
Busy Wait
Each thread wait before printing. And release when the condition is true. I used AtomicInteger for indexToPrint to make this value sync for every thread.
This solution works with n number of threads.
import java.util.concurrent.atomic.AtomicInteger;
class Task extends Thread {
final static private AtomicInteger indexToPrint = new AtomicInteger(0);
static private int threadNumber = 0;
final private int index;
/**
*
*/
public Task() {
index = threadNumber++;
}
private int nextIndex() {
return (index + 1) % threadNumber;
}
#Override
public void run() {
try {
for(int i = 0; i<10; i++){
double dure = Math.random()*200 ;
sleep((long) dure);
while (indexToPrint.get() != index) {
sleep((long) 10);
}
indexToPrint.set(nextIndex());
System.out.println(Thread.currentThread().getName());
}
} catch (Exception e) {}
}
}
wait and notify
A bit more complex to understand, but no useless CPU use. Let's explain how the synchronized block synchronized (indexToPrint) {...} works.
The block is synchronized monitoring the static object indexToPrint. This object is static (common to every thread), so only one thread can simultaneously enter this block.
When one thread enter the block, if its index is different from indexToPrint then the thread is stopped with wait() making it possible for another thread to enter the block. Else, the thread name is printed, the indexToPrint is updated to next thread index and all thread are waken up with notifyAll(). Finally, it left the block.
All threads waiting are now awake, and the actual thread left the block. So one thread can try again to print.
It's important to understand that when a thread is put to wait and then notify, it runs exactly where it was stopped. Here, a thread can be stopped at two positions: before the synchronized block and at the wait call.
The while is very essential here. All thread are waking up with notifyAll(), so after waking up they should test themselves again.
You can find a good documentation here.
The code is based on the previous one. With same use of indexToPrint.
import java.util.ArrayList;
import java.util.concurrent.atomic.AtomicInteger;
class Task extends Thread {
static private final AtomicInteger indexToPrint = new AtomicInteger(0);
static private int threadNumber = 0;
final private int index;
final private static ArrayList<Task> tasks = new ArrayList<>();
/**
*
*/
public Task() {
index = threadNumber++;
tasks.add(this);
}
private int nextIndex() {
return (index + 1) % threadNumber;
}
#Override
public void run() {
try {
for(int i = 0; i<10; i++){
double dure = Math.random()*200 ;
sleep((long) dure);
synchronized (indexToPrint) {
while (indexToPrint.get() != index) {
indexToPrint.wait();
}
indexToPrint.set(nextIndex());
System.out.println(Thread.currentThread().getName());
indexToPrint.notifyAll();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
The random sleep time can cause the unexpected result also within the main method making the main thread sleep between the start of Thread1 and Thread2 can help you to know who is the first thread that will start the print task , after that you should give the right sleep time inside the task to give the Threads the possibility to prints alternatively .
class Task extends Thread {
#Override
public void run() {
try {
for(int i = 0; i<10; i++){
sleep(2000);
System.out.println(Thread.currentThread().getName());
}
} catch (Exception e) {
}
}
}
public class App {
public static void main(String[] args) {
Task t1 = new Task() ;
Task t2 = new Task() ;
t1.start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
t2.start();
}
}
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.
This question already has answers here:
IllegalMonitorStateException on wait() call
(12 answers)
Closed 5 years ago.
I am trying to learn Multi threading and for practice, I am trying to print odd & even number using two thread. I have created an object which will act as a lock for the both the threads. When I try to execute it throws java.lang.IllegalMonitorStateException.
class EVENODDimpl implements Runnable {
int num;
int temp = 0;
Object lock = new Object();
public EVENODDimpl( int num) {
this.num = num;
}
public void run() {
try {
synchronized (lock) {
while(temp<num) {
temp++;
System.out.println(Thread.currentThread().getName()+" "+temp);
this.notify();
this.wait();
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Main Method:
public class EVENODD {
public static void main(String[] args) {
int i = 10;
EVENODDimpl ei = new EVENODDimpl(i);
Thread t1 = new Thread( ei,"EvenThread");
Thread t2 = new Thread( ei,"OddThread");
t1.start();
t2.start();
try {
t1.join();
t2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
You wait and notify on this, but you should wait and notify on lock because you synchronize on lock, you can't wait and notify on other object than the one on which you're synchronizing, working version:
class EVENODDimpl implements Runnable {
int num;
int temp = 0;
Object lock = new Object();
public EVENODDimpl( int num) {
this.num = num;
}
public void run() {
try {
synchronized (lock) {
while(temp<num) {
temp++;
System.out.println(Thread.currentThread().getName()+" "+temp);
lock.notify();
lock.wait();
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
As it said from the javadoc
Thrown to indicate that a thread has attempted to wait on an object's monitor or to notify other threads waiting on an object's monitor without owning the specified monitor.
This means that your methods notify and wait should own monitor. Or in other words the object that is calling these method must be synchronized. Your this object is not synchronized. That's why you get this exception. Call this method from lock object in your case.
Your logic is still wrong but it is up to you to explore that.
java.lang.IllegalMonitorStateException Exception occur because you are using notify method on the object this.notify() but that Object is not synchronized.
Replace synchronized (lock) with this: synchronized (this)
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.
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.