My Question is related to the Working of two thread at a time,suppose one thread write a file and release the resource to another thread for reading the same file and vice versa.But the communication is not happening properly. here is the code snippet
Thread 1
public void run() {
for(int i=1;i<10;i++) {
System.out.println(i+"i");
System.out.println("writing the file");
try {
synchronized (new A()) {
wait();
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Thread 2
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
for(int j=1;j<10;j++) {
System.out.println(j+"j");
System.out.println("reading the file");
synchronized (new B()) {
notifyAll();
}
}
synchronization happens on a particular monitor object.
In your code you create new monitors for each synchronization block, with the new operator.
So you will never lock the access to this fragment of code because no other monitor can be taken by another thread.
This is the classic "producer consumer/reader writer" concurrency problem. There are several ways you can go about this - Some being slightly outdated however easier to understand for a beginner like yourself.
In order for 2 or more threads to be dependent on each other starting or finishing, there must be a concept of a shared object or variable which can be changed by each thread, to signal the other threads that the current one is finished. It is important that only one thread is changing the shared object at any one time (Also known as the critical section). In this case, you could use some Java 8 concurrency features to synchronise these 2 threads. Heres a simple example below using some Java 8 Concurrency syntax, namely the ReadWriteLock, which has been created especially for this use case.
public class ReaderWriterProblem {
private ReentrantReadWriteLock theLock = new ReentrantReadWriteLock(true);
public static void main(String[] args) {
ReaderWriterProblem rwProblem = new ReaderWriterProblem();
Reader reader1 = new Reader(theLock);
Writer writer1 = new Writer(theLock);
new Thread(reader1).start();
new Thread(writer1).start();
}
private class Reader implements Runnable {
private ReentrantReadWriteLock theLock;
public Reader(ReentrantReadWriteLock theLock) {
this.theLock = theLock;
}
public void run() {
try {
theLock.readLock().lock();
System.out.println("Currently Reading!");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
}
} finally {
theLock.readLock().unlock();
}
}
}
private class Writer implements Runnable {
private ReentrantReadWriteLock theLock;
public Writer(ReentrantReadWriteLock theLock) {
this.theLock = theLock
}
public void run() {
try {
theLock.writeLock().lock();
System.out.println("Currently Writing!");
try {
Thread.sleep(4000);
} catch (InterruptedException e) {
}
} finally {
theLock.writeLock().unlock();
}
}
}
}
This is a very basic example but the ReadWriteLock actually comes with built in support for one writer at any time and many readers. So when a thread holds the write Lock, no other thread can write at the same time, however several threads can hold the read lock at one time.
Other potential solutions to this problem include semaphores and busy wait, which are worth having a look at online.
SHORT ANSWER to why your question was wrong - You need to synchronise shared objects and variables, not the instances of classes that are executing the concurrent statements. Hope this helps you understand a little more. Notice how the lock is shared between the reader and writer.
Related
I am starting these threads:
ThreadingHDFSUsage HDFSUsage=new ThreadingHDFSUsage(dcaps);
ThreadingRAMandContainers RAMandContainers=new ThreadingRAMandContainers(dcaps);
ThreadingCoreNodesHDFSUsage CoreNodesHDFSUsage=new ThreadingCoreNodesHDFSUsage(dcaps);
ThreadingApplicationMonitoring ApplicationMonitoring= new ThreadingApplicationMonitoring(dcaps);
How should i wait for all these threads to complete before doing some other operation.
My sample thread class code for one thread operation is:
public class ThreadingHDFSUsage extends Thread {
//private PhantomJSDriver driver;
private DesiredCapabilities dcaps;
public ThreadingHDFSUsage(DesiredCapabilities dcaps) {
// TODO Auto-generated constructor stub
this.dcaps = dcaps;
}
public void run(){
System.out.println("task HDFS Usage");
PhantomJSDriver driver = new PhantomJSDriver(dcaps);
try {
Thread.sleep(10000);
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
System.out.println(".........HDFS Usage..........");
String OverallHDFSUsage[] = null;
try {
OverallHDFSUsage = HDFSUsage.getWebData(driver,"http://1.2.3.4:8888/dfshealth.html#tab-overview","//*[#id=\"tab-overview\"]/table[2]/tbody/tr[2]/td","");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
String OverallHDFSUsage1 = OverallHDFSUsage[0];
}
}
Similarly, I have relevant code for other threads.
So, how do i wait for all these 4 thread operation to complete?
Just join() them again:
HDFSUsage.join();
RAMandContainers.join();
CoreNodesHDFSUsage.join();
ApplicationMonitoring.join();
Each join() waits for the specific thread to finish.
There's also CompletionService in JDK concurrent package. To use it, you switch from explicit Threads to tasks, represented as instances of Callable<ResultType> or Runnable. While code may look slightly more complicated, it is quite convenient, once you became used to it:
import java.util.concurrent.*;
class Test {
public static void main(String[] args) throws InterruptedException, ExecutionException {
CompletionService<String> completionService = new ExecutorCompletionService<>(Executors.newCachedThreadPool());
completionService.submit(() -> {
Thread.sleep(5000);
return "sleeped for 5000 millis";
});
completionService.submit(() -> {
Thread.sleep(1000);
return "sleeped for 1000 millis";
});
// etc
System.out.println("Completed: " + completionService.take().get());
System.out.println("Completed: " + completionService.take().get());
}
}
Both of the other answers are correct, but for completeness, there's yet another way to do what you want using a Semaphore. This method won't yield results different from any of the other answers, but may be faster if any of your threads have to do something expensive after the results you want are obtained, prior to returning. Inside each of your threads, call s.release() as soon as all pertinent work is finished. Your controller thread might look like this ...
Semaphore s = new Semaphore(0);
//start all four of your threads here and pass 's' to each
s.acquire(4);
... and your worker threads might look like this:
#Override
public void run(){
//compute results
s.release(1);
//do expensive cleanup and return
}
I have myThread.wait() that is in synchronzed(myThread) block. And I have Myrunner that implements runnable. I would like to tell notify() from myRunner, but it is not monitor object. Is it possible to get handle of myThread from myRunnable to make notify? Is there any other solution? Extend myRunnable from Thread and run it is not good for some reasons related on my code specific.
public class ThreadMain {
public Thread reader;
private class SerialReader implements Runnable {
public void run() {
while (true) {
try {
Thread.sleep(3000);
synchronized(this) {
System.out.println("notifying");
notify();
System.out.println("notifying done");
}
} catch (Exception e) {
System.out.println(e);
}
}
}
}
ThreadMain() {
reader = new Thread(new SerialReader());
}
public static void main(String [] args) {
ThreadMain d= new ThreadMain();
d.reader.start();
synchronized(d.reader) {
try {
d.reader.wait();
System.out.println("got notify");
} catch (Exception e) {
System.out.println(e);
}
}
}
}
Both threads should synchronize using the same object. Also, you should really not use an existing object to syncronize, but create a object to be used explicitly for synchronization, like
Object lock = new Object();
Also see https://www.securecoding.cert.org/confluence/display/java/LCK01-J.+Do+not+synchronize+on+objects+that+may+be+reused
If the lock is to be used to interact with your thread, you can put it in the thread and provide a getter for anyone to use it.
To notify() a wait()ing thread you much have a reference to the object it is wait() on and you must be able to acquire a lock on it. I suggest you also change a state which notifying and you check that state change in a loop when wait()ing.
The only other option is to change the code of the waiting thread.
How can I notify Thread t1 and Thread t2 at the same time (so it is the same probability to get hey 1 as hey2 first)? I've tried notifyAll, but couldn't make it work.
class Thr extends Thread
{
Thr () throws InterruptedException
{
Thread t1 = new Thread() {
public synchronized void run()
{
while (true)
{
try {
wait();
} catch (InterruptedException e1) {
e1.printStackTrace();
}
try
{
Thread.sleep(1500);
} catch (Exception e) { }
System.out.println("hey 1");
}
}
};
Thread t2 = new Thread() {
public synchronized void run()
{
while (true)
{
try {
wait();
} catch (InterruptedException e1) {
e1.printStackTrace();
}
try
{
Thread.sleep(1500);
} catch (Exception e) { }
System.out.println("hey 2");
}
}
};
t1.start();
t2.start();
}
public static void main(String args[]) throws InterruptedException
{
new Thr();
}
}
You should wait on a shared object and use notifyAll as in:
class Thr extends Thread
{
Thr () throws InterruptedException
{
final Object lock = new Object ();
Thread t1 = new Thread() {
public void run()
{
try {
synchronized (lock) {
lock.wait();
}
} catch (InterruptedException e1) {
e1.printStackTrace();
}
System.out.println("hey 1");
}
};
Thread t2 = new Thread() {
public synchronized void run()
{
try {
synchronized (lock) {
lock.wait();
}
} catch (InterruptedException e1) {
e1.printStackTrace();
}
System.out.println("hey 2");
}
};
t1.start();
t2.start();
synchronized (lock) {
lock.notifyAll ();
}
}
public static void main(String args[]) throws InterruptedException
{
new Thr();
}
}
The right way to do this is to use notifyAll. The real problem with your code seems to be that you have two threads waiting for notifications on different mutexes. You need them to wait on a single object ... as described in #ShyJ's answer.
Note that there is NO WAY that you can code this so that the notification is guaranteed to be delivered first to either thread with equal probability:
The Java threading specs make no guarantees of fairness in wait / notify.
The thread scheduler implemented (typically) at the OS-level (typically) makes no such guarantees either.
The point is that the application has no control over this. The best approach is to just let wait/notifyAll do what they normally do, and design your application so that any bias in the thread scheduling does not affect the application's behaviour in an important way.
(FWIW, the usual problem is that people explicitly or implicitly assume non-randomness ... and get burned when threads get scheduled in an unexpectedly random order.)
I highly recommend avoiding the use of wait/notify and use something more robust. The problem is that using wait/notify in any combination will likely result in a race condition.
The only way to give equal probability to them academically is to create two Semaphore objects, have the threads try to acquire them, and use Random to choose which one to release first. Even then, if the scheduler decides to run the first one that tried to obtain the lock, then you get bias there anyway, regardless of whether or not the Sempahore is fair. This forces you to wait until the first thread is done before running the second, such as via Thread.join.
Bottom line, the only way to guarantee order in a concurrent system is to force them into a single-threaded format, which throws out the whole point of having them concurrent in the first place.
If you are using Java versions greater than 1.4, then it would greatly simplyfy your task by using any of the concurrent locks:
java.util.concurrent.locks specially the ReadWrite type.
For now for message passing to all the threads at the same type - implement Observer Pattern
I am studying for java certification, and I see this example from Mughal's book:
public class Smiley extends Thread
{
#Override
public void run()
{
while(true)
{
synchronized(this)
{
try
{
System.out.print(":");
Thread.sleep(100);
System.out.print("-");
Thread.sleep(100);
System.out.println(")");
Thread.sleep(100);
}
catch(InterruptedException e)
{
e.printStackTrace();
}
}
}
}
public static void main(String[] args)
{
new Smiley().start();
new Smiley().start();
}
}
The purpose is to print one smiley :-) per line. My question is that why synchronizing on instance (this) doesn't achieve this? Why we need to synchronize on static level?
Thanks,
Because note that the main() function creates two Smiley classes. And they each run on their own thread. Since they are locking on this, they are both going to acquire the lock immediately, with no contention with the other thread. In this case, their locking scheme of synchronize(this) accomplishes nothing.
When dealing with multithreading issues, you have to think "What am I trying to protect?" In this case, you need to protect System.out, to ensure that you are accessing it in the order you want to. Since System.out is static, you need some sort of outer scope lock which each thread has to acquire before they can write to it.
You can use ReentrantLock to achieve this.
Please do not use synchronized (this) - this is bad practice in general
As explained above - the lock should be shared between the two threads, and in this case the lock is the instance of each class (i.e - the objects created by new Smiley).
What you should have is a shared lock, maybe by using a static variable, which is shared among all instances of the same class,
or pass a lock as parameter to the CTOR of smiley.
I will give example for the 2nd option, based on the suggestion of #Jonathon Reinhart to use a Reentrant Lock
public class Smiley extends Thread
{
private ReentantLock lock;
public Smiley(ReentrantLock lock) {
this.lock = lock;
}
#Override
public void run()
{
while(true)
{
try {
lock.lock();
System.out.print(":");
Thread.sleep(100);
System.out.print("-");
Thread.sleep(100);
System.out.println(")");
Thread.sleep(100);
}
catch(InterruptedException e) {
e.printStackTrace();
}
finally {
lock.unlock();
}
}
}
}
public static void main(String[] args)
{
ReentrantLock lock = new ReentantLock();
new Smiley(lock).start();
new Smiley(lock).start();
}
Some pointers -
a. bare in mind that the unlock code must be in a finally clause - this is a good practice (you can also have try block and finally block, without a catch block).
b. You may consider replacing ReentrantLock with other locks from java.util.concurrent package - based on your needs
It's actually two questions you are asking, and the answers are:
Why synchronizing on instance (this) doesn't achieve this?
Because you are acquiring two different implicit locks, so the instructions inside the synchronized block are allowed to be executed concurrently by the two threads and may be actually interleaved.
Why we need to synchronize on static level?
You don't need to synchronize on a static level. You need to synchronize on the same instance of an object shared by the threads.
The simplest way to achieve what you want is to synchronize on System.out in the following way:
#Override
public void run() {
while (true) {
synchronized (System.out) {
try {
System.out.print(":");
Thread.sleep(100);
System.out.print("-");
Thread.sleep(100);
System.out.println(")");
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
I have a project for my "Operating Systems". I need to write 2 programs with java...
write a program that produce Water with 2 method Oxygen and Hydrogen.
method Oxygen produce one Oxygen and method Hydrogen produce one hydrogen. when 2 Hydrogen and one Oxygen was existed H2O created. I must write this with with Semaphores and threads.
Write the above problem with Monitors and Sychronize.
I've writed some code for this but it gives illegal monitor exeption...
please help me to correct it...
This is my code:
// class for implement Thread for oxygen
public class Thread_O implements Runnable {
public void run() {
thread t = new thread();
try {
t.oxygen();
} catch (InterruptedException ex) {
Logger logger = Logger.getLogger(Thread_O.class.getName());
logger.log(Level.SEVERE, null, ex);
}
}
}
// class for implement Thread for Hydrogen
public class Thread_H implements Runnable {
public void run() {
thread t = new thread();
try {
t.Hydrogen();
} catch (InterruptedException ex) {
Logger logger = Logger.getLogger(Thread_H.class.getName());
logger.log(Level.SEVERE, null, ex);
}
}
}
//class for method Oxygen and Hydrogen
public class thread {
Semaphore O = new Semaphore(0, true);
Semaphore H = new Semaphore(0, true);
Semaphore H2O = new Semaphore(0, true);
Semaphore safe = new Semaphore(1, true);
public void oxygen() throws InterruptedException {
safe.wait();
H.wait();
H.wait();
H2O.release();
H2O.release();
Safe.release();
// System.out.println("O2...!");
}
public void Hydrogen() throws InterruptedException {
H.release();
H2O.wait();
// System.out.println("H2...!");
}
}
and in action of Oxygen Button:
Thread th = new Thread(new Thread_O());
th.start();
I'm not going to decode your homework for you, but an IllegalMonitorException is thrown when you're trying to wait() on an object without being synchronized. So to wait for an object called list:
synchronized (list) {
try {
list.wait();
} catch(Throwable t) {
t.printStackTrace();
}
}
You have to understand how the producer/consumer mechanism work.
Here you'll have one consumer thread and two producers.
First you'll have one thread producing oxygen, and other producing hydrogen.
Then, those molecules should be places "somewhere" ok? That "something" is the thing that has to be monitored and synchronized.
So it should go something like this:
class Water {
char [] waterMolecule = new char[3]; // <-- synchronize access to this
char hydrogen(){
return 'H';
}
char oxygen() {
return 'O';
}
void produce() {
Thread t = new Thread( new Runnable() {
synchronize( waterMolecule ) {
waterMolecule[0] = hydrogen();
}
}):
.... produce the others
}
void consume() {
synchronize watermolecule
if waterMolecule is complete
create water and clean out the molecule.
}
}
That's the basic idea.
Just bear in mind that you won't be able to produce another particle of oxigen until the previous one has been consumed.
Also you must always call wait in a while loop
Here's how that wait/synchronize should be coded.
Here's a number of producer/consumer samples.
Although your homework is already due, I'd like to propose CyclicBarrier as the best solution for this scenario.
It allows some kind of rendezvous for the different threads (here: your molecule producers) and triggers the execution of an additional runnable on completition (here: creation of h20).