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).
Related
I have been assigned an exercise from my uni professor that goes as follow:
"A fence object is an object that has a collection of objects, and can wait on any of those objects is signaled. There is an add(Object) method, which adds an object to the collection. There is also an await() method: this allows to wait on any object of the collection to be signaled. Whenever the add(Object) method is called while the await() method is active, the argument of the add is put in queue. Write the source code using the following interface: ".
public interface Fence {
public void await() throws InterruptedException;
public void add(Object o);
}
So, only when the same number of notify() and objects in queue (aka the number of add(Object) ) are called, the await() terminates and the object in the queue are finally added to the collection. <- this is something I got wrong and realized after writing my code
I did make the implementation as follow:
import java.util.LinkedList;
public class FenceImpl2 implements Fence{
private LinkedList<Object> collection;
private Object mutex; ;
static boolean iswaiting = false;
public FenceImpl2() {
this.collection = new LinkedList<Object>();
this.mutex = new Object();
}
#Override
public void await() throws InterruptedException {
Thread t1 = new Thread(new Runnable() {
#Override
public void run() {
try {
synchronized(mutex) {
mutex.wait();
iswaiting = true;
}
} catch (InterruptedException e) {
e.printStackTrace();
}}});
t1.start();
}
#Override
public void add(Object o) {
Thread t2 = new Thread(new Runnable() {
#Override
public void run() {
synchronized(mutex){
if(iswaiting == true) {
try {
mutex.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
else {
collection.add(o);
}
}}});
t2.start();
}
public Object getList() throws InterruptedException {
synchronized(mutex){
System.out.println("Collection list: \n");
for(Object o : collection) {
System.out.println(o);
Thread.sleep(1000);
}
System.out.println("------- \n");
return collection;
}
}
public void notification() {
Thread thread = new Thread(()->{
synchronized(mutex){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
mutex.notify();
}
});
thread.start();
}
public static void main(String[] args) throws InterruptedException {
FenceImpl2 f = new FenceImpl2();
Object o1 = 1;
Object o2 = 2;
Object o3 = 3;
Object o4 = 70;
f.add(o1);
System.out.println("Add 1");
f.add(o2);
System.out.println("Add 2");
f.add(o3);
System.out.println("Add 3");
f.await();
System.out.println("Await active ");
f.add(o4);
System.out.println("Aggiungo 70 - Shouldn't appear. Forced in queue");
f.getList();
f.notification();
System.out.println("Notify() sent - 70 should now appear in the collection");
f.getList();
}
}
After submitting it to my professor I have been told two things:
The synchronization is not correct: the await "unlocks" after the first notify and that shouldn't happen because it doesn't wait for the other (if any) objects that are in queue to be notified.
^Let me say I know how to fix that easily but
Although it's a minor mistake, the methods await, add and notification SHOULD NOT be done using asynchronous dedicated threads.
Here it finally comes my problem. How am I supposed to use wait() on a lock object and then notify() if I am not using dedicated threads?
I tried removing the threads but obviously as soon as I'm calling mutex.wait() the program locks and the code right after that calls the notification method is not reached.
Why did my professor tell me using threads is wrong?
How can I use a wait() and then call a notify() in two separate methods without having the program lock?
Here's an example of what I mean:
public class testw {
private Object mutex;
boolean condition = false;
public testw() {
this.mutex = new Object();
}
public void startWait() {
synchronized(mutex) {
try {
Thread.sleep(1000);
condition = true;
while(condition == true) {
System.out.println("Waiting!");
mutex.wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void sendNotify() {
synchronized(mutex) {
try {
Thread.sleep(3000);
System.out.println("Notify!, not waiting anymore");
condition = false;
mutex.notify();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
testw t = new testw();
t.startWait();
t.sendNotify();
}
Without using threads, when I startWait() is called the main thread goes in wait, but there's no way that sendNotify() to be called and the programs freezes. Is there a way to do this without using threads or am I missing something?
Thank you very much.
I have been told...Although it's a minor mistake, the methods await, add and notification SHOULD NOT be done using asynchronous dedicated threads.
The whole point of a method named await() is that it should not return until the event that the caller wants to wait for has happened.
Your await() method doesn't wait. It creates a new thread and then it immediately returns. The new thread waits for something, but after that it just dies without doing anything useful. The new thread might as well not exist at all.
Your add(o) method doesn't make a whole lot of sense either. I'm not even sure what you were trying to do with it, but I think you need to take a step back, and try to explain to the duck why you thought that either of those two methods should create a new thread.
How am I supposed to use wait() on a lock object and then notify() if I am not using dedicated threads?
The Oracle "Guarded Blocks" tutorial is an oldie but a goodie. If you work through it to the end, it should give you a pretty clear idea of how and why and when to use wait() and notify().
https://docs.oracle.com/javase/tutorial/essential/concurrency/guardmeth.html
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.
I have started learning threads and tried Producer consumer problem in Java using concurrent package introduced in JDK 5.0 I have written the following code:
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
class Producer implements Runnable {
private final BlockingQueue<Integer> objqueue;
Producer(BlockingQueue<Integer> obj) {
objqueue = obj;
}
#Override
public void run() {
int i = 0;
while (i < 10) {
try {
System.out.println("Put : " + i);
objqueue.put(i);
} catch (InterruptedException e) {
}
i++;
}
}
}
class Consumer implements Runnable {
private final BlockingQueue<Integer> objqueue;
Consumer(BlockingQueue<Integer> obj) {
objqueue = obj;
}
#Override
public void run() {
while (true) {
try {
System.out.println("Got : " + objqueue.take());
} catch (InterruptedException e) {
}
}
}
}
public class PCMain {
public static void main(String[] args) {
// create shared object
BlockingQueue<Integer> obj = new LinkedBlockingQueue<Integer>();
Thread prod = new Thread(new Producer(obj));
Thread cons = new Thread(new Consumer(obj));
prod.start();
cons.start();
}
}
The program is not terminating when the producer has produced up to 9 and consumer consumed up to 9. Should I remove the while loop which is true forever in Consumer.
How can I make it for more than one Producer and one Consumer?
Thanks.
Well you have two threads, one should stop once i == 10. The other thread is in an infinite loop though. You need to signal to the consuming thread that the application should end. Look at the Poison Pill as a way of telling the second thread to stop.
The program itself won't stop until that consuming thread completed.
Removing while loop will cause consumer will consume only 1 object given by producer.
Better to go Excecuter framework. It is having Thread Factory and Thread Pool.You can use to implement the same.
I think the easiest way to "fix" your code is to make the consumer a daemon thread.
Thread prod = new Thread(new Producer(obj));
Thread cons = new Thread(new Consumer(obj));
cons.setDaemon( true );
prod.start();
cons.start();
This really isn't a general solution, but a good trick to keep in mind when it's inconvenient to signal a thread to stop.
i want to pause thread which is writing messages in file by iterate message list. When message list is empty i want thread to stop and thread is resumed when message in a list.
I know stop,suspend (),resume methods is deprecated but if thread is continuously in background it consumes cpu. I did lots of googling but can't find proper answer. please any one help me out
Here is my code:
private Thread mFileWriterThread = new Thread() {
#Override
public synchronized void run() {
while (mIsRunning) {
synchronized (mMessageList) {
Iterator it = mMessageList.iterator();
while ((it.hasNext())) {
String message = (String) it.next();
writeToFile(fileOutputStream, message);
mMessageList.remove(message);
}
}
}
}
};
That's what a BlockingQueue exists for. It has a take() method that forces a thread to block until an Object is avalaible. Your problem can be solved with a simple producer-consumer design.
I'm pasting here a minimal snippet taken from the Oracle examples:
class Producer implements Runnable {
private final BlockingQueue queue;
Producer(BlockingQueue q) { queue = q; }
public void run() {
try {
while (true) { queue.put(produce()); }
} catch (InterruptedException ex) { ... handle ...}
}
Object produce() { ... }
}
class Consumer implements Runnable {
private final BlockingQueue queue;
Consumer(BlockingQueue q) { queue = q; }
public void run() {
try {
while (true) { consume(queue.take()); }
} catch (InterruptedException ex) { ... handle ...}
}
void consume(Object x) { ... }
}
Of course Consumer an Producer have to share the queue somehow (just passing it to the constructor as shown in the example will work fine).
You want to use wait() to make the thread block*. And then call notify() to wake up the thread again. Google for "java wait notify" will give you a tutorial.
*Block here mean wait without using any resources, until an other thread wake it up.
How do we implement efficient exception handling when using threads.
I have a main program which creates 3 threads. How do we handle the exceptions for the exceptions thrown during the execution of thread?
Can we use the try/catch block or uncaughtexception. If so, can you please share some samples.
public class MyThreadTest {
public static void main(String[] args) {
Thread newThread = new Thread(new ThreadWithException());
// Add the handler to the thread object
newThread.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler(){
#Override
public void uncaughtException(Thread t, Throwable e) {
System.out.println("ERROR! An exception occurred in " + t.getName() + ". Cause: " + e.getMessage());
}
});
newThread.start();
}
}
/**
* This thread throws a custom exception in its run method.
*/
class ThreadWithException implements Runnable {
#Override
public void run() {
throw new RuntimeException("Application Specific Exception!!");
}
}
Either you can use:
Thread#setUncaughtExceptionHandler to specify some code that is run when an exception is thrown (outside of normal program flow), or:
ExecutorService#invokeAll to run all of your blocks, and inspect the returned list for Future#get()'s throwing of ExecutionException. Another option is CompletionService, but this is slightly harder to use for such a simple case.
You can use try / catch block strategy:
Thread t = new Thread() {
#Override
public void run() {
try {
//..thread code
} catch (Exception e) {
}
}
};
It is easy to implement but in case of exception main thread of your application will never know what happened inside of child thread.
Better method would be to spawn threads using ExecutorService (as mentioned by FauxFaux). This will allow you to easily pass information about the error to main thread. Besides that, using ExecutorService allows you to write less code. You won't have to manage threads in your code but leave it for ExecutorService instead.
beacuse , recently, I have write a program with about 3 threads in order to fill a lot data from mysql and mongoDb to ElasticSearch. I share u my code.
I use java.util.concurrent.Executors.
First I have a main class. It calls
public void start() throws Exception {
this.logger.info("Main: Start the worker manually");
schedulerThreadPool = Executors.newScheduledThreadPool(this.maxNumberOfThread);
for (int i = 0; i < this.maxNumberOfThread; i++) {
Worker worker = new Worker();
long delay = i * this.sleepBetweenTaskStart;
schedulerThreadPool.scheduleAtFixedRate(worker, delay, this.minTimeBetweenEachTask, TimeUnit.MILLISECONDS);
}
}
And Worker implements Runnable and get Thread Id by below code.
this.threadId = Thread.currentThread().getId();
And just try catch in each Worker. Everything works normally.
#Override
public void run() {
try {
do...
} catch (Exception e) {
e.printStackTrace();
}
}