I am a bit stumped on a new concept I am learning in my concepts of programming languages class. Any info would be great. Reader Writer Problem as follows:
This classical problem requires process synchronization for reading and writing. Therefore, you need a synchronization controller before you define and create threads for reading and writing. The following is a controller class (with two methods left out for you to implement). To keep the programming simple, when you write thread classes for reading and writing (say, three readers and one writer), you only need to symbolically print a message when starting reading or writing, and print another message when finishing reading or writing (thus there is no need to create actual shared content each thread reads or writes about).
Here is what I have. I think I am missing something fundamental with threads. Please note that the controller class and methods is given and required, except the startWriting() and stopWriting() must be implemented by me. Thank you.
class Controller {
private int activeReaders = 0;
private boolean writerPresent = false;
protected boolean writeCondition() {
return activeReaders == 0 && !writerPresent;
}
protected boolean readCondition() {
return !writerPresent;
}
protected synchronized void startRead() {
while (!readCondition())
try { wait(); } catch (InterruptedException ex) {}
++activeReaders;
}
protected synchronized void stopRead() {
--activeReaders;
notifyAll();
}
protected synchronized void startWriting(){
writerPresent = true;
System.out.println("Writing has begun");
}
protected synchronized void stopWriting(){
System.out.println("Reading is now available");
writerPresent = false;
}
public static void main(String [] args){
Controller c = new Controller();
Thread tRead1 = new Thread(new Runnable() {
#Override
public void run(){
c.startRead();
System.out.println("Reader 1 has started reading");
c.stopRead();
System.out.println("Reader 1 has stopped reading");
}
});
Thread tRead2 = new Thread(new Runnable() {
#Override
public void run(){
c.startRead();
System.out.println("Reader 2 has started reading");
c.stopRead();
System.out.println("Reader 2 has stopped reading");
}
});
Thread tRead3 = new Thread(new Runnable() {
#Override
public void run(){
c.startRead();
System.out.println("Reader 3 has started reading");
c.stopRead();
System.out.println("Reader 3 has stopped reading");
}
});
Thread tWrite1 = new Thread(new Runnable() {
#Override
public void run(){
c.startWriting();
c.stopWriting();
}
});
tRead1.start();
tRead2.start();
tWrite1.start();
try {
tWrite1.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
tRead3.start();
}
}
First, I recommend you go to the javadocs and read the method definitions for wait, notify, and notifyall. This is the basic waiting / locking / notifying system in Java.
In terms of Readers and Writers, the readers should all be reading from the writer, and put into suspension using wait on the writer if there is no content available. If you have multiple writers, you can do the same thing with the readers waiting on a messagequeue. When the writer writes and has more data to be consumed by a reader, it should call notify on itself (the writer) to wake one consumer up to grab the new data.
And to give you an idea of when you could/should use notifyAll:
Thread.join works by invoking wait on the Thread being joined with. Upon thread death, Thread calls notifyAll to wake up all threads that are waiting for it to finish.
Related
I am trying to implement Linux pipe operator | using java. The basic idea is assigning connected PipedInputStream and PipeOutputStream to the two commands and they can perform their actions simultaneously.
The implementation is as follows:
PipedOutputStream pOutputStream = new PipedOutputStream();
PipedInputStream pInputStream = new PipedInputStream();
pOutputStream.connect(pInputStream);
Thread thread1, thread2;
thread1 = new Thread(){
public void run() {
try {
new Call(pipe.cmd1).eval(CommandHandler.this, inputStream, pOutputStream);
pOutputStream.close();
} catch (Exception e) {
thread2.interrupt(); // cannot do this as it may not have been initialized
}
}
};
thread2 = new Thread() {
public void run() {
try{
new Pipe(pipe.cmd2).eval(CommandHandler.this, pInputStream, outputStream);
// pInputStream.close();
} catch (Exception e) {
// kill the first thread when the second one raises an exception
thread1.interrupt();
throw e;
}
}
};
thread1.start();
thread2.start();
// waiting for the two threads to die before carry on
thread2.join();
thread1.join();
I would like to interrupt the second thread when the first one raises an exception, just like what I did in thread2 catch. The problem is thread2 is assigned latter so I cannot access it within thread1. I tried to inialize thread1&2 with null values but then they have to be final since they are in an enclosing scope.
Forgive me if it is a stupid question, I just get started to explore multi-threading in java.
** UPDATE **
Thanks to Phil's suggestions. I changed the two anonymous inner classes to two inner classes that extends Thread.
class Thread1 extends Thread{
public Thread counterThread;
public void run() {
try {
new Call(pipe.cmd1).eval(CommandHandler.this, inputStream, pOutputStream);
pOutputStream.close();
} catch (Exception e) {
// kill thread 2
if (counterThread != null) counterThread.interrupt();
}
}
public void setThread(Thread thread) {
counterThread = thread;
}
};
class Thread2 extends Thread {
public Thread counterThread;
public void run() {
try{
new Pipe(pipe.cmd2).eval(CommandHandler.this, pInputStream, outputStream);
// pInputStream.close();
} catch (Exception e) {
// kill the first thread when the second one raises an exception
if (counterThread != null) counterThread.interrupt();
throw e;
}
}
public void setThread(Thread thread) {
counterThread = thread;
}
};
Thread1 thread1 = new Thread1();
Thread2 thread2 = new Thread2();
thread1.setThread(thread2);
thread2.setThread(thread1);
Given the code you've started with, two possibilities come to mind. There may be better ideas, but here they are:
(1) Add an additional public method in your anonymous inner class definition that allows you to store a reference to an external thread to be messaged/interrupted. After you create both threads, store a reference of each in the other.
(2) Store a reference to a class (possible the same class that creates and launches the threads) that will hold references to each thread. Have the catch method call a method in that launching class that will message (via loose coupling pattern) or interrupt the counterpart.
Due to the fact that in almost every question regarding the use of Thread.sleep it is mostly indicated to use it only in certain situations, I come to ask you if it is correct to use it in my case or if there is a better way to do it.
The operating system is Linux(Debian), in which a bash script is running that is detecting when a device (more specifically, a storage device) is inserted/removed, and then writes into a FIFO a string under the type "ADD {path-to-dev}" or "REM {path-to-dev}".
I created a small app in java which makes use of two threads. The first thread will call upon a read method that parses the String to the standard output, after which it will wait(). The second thread will check if the FIFO is empty or not and then, when it sees that a String has been inserted then it will call notify() so the other thread will print the String in there and so on. Inside the loop where it checks if the FIFO has data or not, I call Thread.sleep(1000), and I am unsure whether this is a good approach or not. I will present the code which handles all the action.
First, the class which has the methods of reading:
public class Detect {
private File file;
private BufferedReader read;
private volatile boolean readable;
private static String readFromFile;
public Detect() throws FileNotFoundException {
file = new File("/hardware_stuff/hardware_events");
read = new BufferedReader(new FileReader(file));
readable = true;
}
synchronized String readFromFifo() {
while (!readable) {
try {
wait();
} catch (InterruptedException ex) {
System.out.println("Interrupted during the wait for read.");
}
}
try {
while (read.ready()) {
readFromFile = read.readLine();
}
} catch (IOException ex) {
System.out.println("Error in reading from FIFO.");
}
readable = false;
notify();
return readFromFile;
}
synchronized void waitForFifo() {
while (readable) {
try {
wait();
} catch (InterruptedException ex) {
Logger.getLogger(Detect.class.getName()).log(Level.SEVERE, null, ex);
}
}
try {
while (!read.ready()) {
Thread.sleep(1000);
System.out.println("Sleeping due to lack of activity in FIFO in thread : " + Thread.currentThread().getName());
}
} catch (IOException | InterruptedException ex) {
Logger.getLogger(Detect.class.getName()).log(Level.SEVERE, null, ex);
}
readable = true;
notify();
}}
Next, the thread which will read from it.
public class ReadThread extends Thread {
Detect detect;
private boolean shouldBeRunning;
public ReadThread(Detect detect) {
this.detect = detect;
shouldBeRunning = true;
}
#Override
public void run() {
while (shouldBeRunning) {
String added = detect.readFromFifo();
System.out.println(added);
}
}
public void stopRunning() {
shouldBeRunning = false;
}}
Finally, the thread which will check if the FIFO is empty or not.
public class NotifyThread extends Thread {
Detect detect;
private boolean shouldBeRunning;
public NotifyThread(Detect detect) {
this.detect = detect;
shouldBeRunning = true;
}
#Override
public void run() {
while (shouldBeRunning) {
detect.waitForFifo();
}
}
public void stopRunning() {
shouldBeRunning = false;
}}
In main I just create the threads and start them.
Detect detect = new Detect();
NotifyThread nThread = new NotifyThread(detect);
ReadThread rThread = new ReadThread(detect);
nThread.start();
System.out.println("Started the notifier thread in : " + Thread.currentThread().getName());
rThread.start();
System.out.println("Started the reading thread in : " + Thread.currentThread().getName());
Is there any alternative to calling sleep or another approach I can take to replace the sleep with something else? I have already read other questions related to this topic and I am still uncertain/have not understood whether this sort of case is indicated for sleep or not.
UPDATE: As #james large said, there was no need to poll for ready. I was not aware that if there is no line, the readLine() will 'sleep' and there was no need to poll it after all. I removed the notifier thread, and I simply kept the ReadThread which will call the Detect readFromFifo() method and it all works good. #dumptruckman, thanks for the suggestion. Although it doesn't apply to my case, I didn't know of the WatchService and it was a good read, good stuff to know. #Nyamiou The Galeanthrope, the timer would have been useful, but as I already said, I only keep one thread to execute the same method and it works as intended.#Krzysztof Cichocki, thanks for pointing out there are issues. I was aware of that, otherwise I wouldn't have asked this question.
Multiple workers are processing from a queue and when a database failure occurs it will contact a supervisor that will then lock all worker threads and poll the database at an interval until it is up and it will then release all the threads so they can continue processing. The worker threads can either advance or wait with the processing and the supervisor thread can lock or unlock.
I was thinking of an interface like this. What synchronization primitives would you use? Actors would be a good solution but i don't have the time for a rewrite.
public interface Latch {
/**
* This method will cause a thread(s) to only advance if the latch is in an open state. If the
* latch is closed the thread(s) will wait until the latch is open before they can advance.
*/
void advanceWhenOpen();
/**
* Close the latch forcing all threads that reaches the latch's advance method to wait until
* its open again.
*/
void close();
/**
* Opens the latch allowing blocked threads to advance.
*/
void open();
boolean isOpen();
}
What you want is not really a "latch" - at least the "Java Concurrency in Practice" book says that "Once the latch reaches the terminal state, it cannot change state again, so it remains open forever."
But you can use CountDownLatch objects in the background - whenever your "Latch" needs to be closed, then you can create a new CountDownLatch object with the count of one and await() on in in your advanceWhenOpen(). I think that from a readability point of view this would be the best solution.
I would use a ReadWriteLock as the synchronization primitive for this purpose. The advantage of a read/write lock as opposed to a simple monitor or mutex is that multiple threads can hold the read lock at any given time. This is advantageous when you have lots of readers (e.g. your thread pool in this case) and only one or few writers (e.g. the thread checking for open/close of the database).
With a single monitor or mutex, your threads will serialize on the one lock, making that section of code contentious.
One option is to proxy the queue to make it pausable when the database is unavailable. Workers can check the paused state of the queue while processing and, if necessary, wait for it to unpause. A basic code-demonstration:
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.atomic.AtomicReference;
public class PausableQueue<T> {
LinkedBlockingQueue<T> q = new LinkedBlockingQueue<T>();
AtomicReference<CountDownLatch> pause = new AtomicReference<CountDownLatch>(new CountDownLatch(0));
public T take() throws InterruptedException {
awaitPause();
return q.take();
}
public void awaitPause() throws InterruptedException {
pause.get().await();
}
public void setPaused(boolean paused) {
if (paused) {
// only update if there are no threads waiting on current countdown-latch
if (!isPaused()) {
pause.set(new CountDownLatch(1));
}
} else {
pause.get().countDown();
}
}
public boolean isPaused() {
return (pause.get().getCount() > 0L);
}
/* *** Test the pausable queue *** */
public static void main(String[] args) {
ExecutorService executor = Executors.newCachedThreadPool();
try {
testPause(executor);
} catch (Exception e) {
e.printStackTrace();
}
executor.shutdownNow();
}
private static void testPause(ExecutorService executor) throws Exception {
final PausableQueue<Object> q = new PausableQueue<Object>();
for (int i = 0; i < 3; i++) {
q.q.add(new Object());
}
final CountDownLatch tfinished = new CountDownLatch(1);
Runnable taker = new Runnable() {
#Override
public void run() {
println("Taking an object.");
try {
Object o = q.take();
println("Got an object: " + o);
} catch (Exception e) {
e.printStackTrace();
} finally {
tfinished.countDown();
}
}
};
executor.execute(taker);
tfinished.await();
final CountDownLatch tstarted2 = new CountDownLatch(2);
final CountDownLatch tfinished2 = new CountDownLatch(2);
taker = new Runnable() {
#Override
public void run() {
println("Taking an object.");
tstarted2.countDown();
try {
Object o = q.take();
println("Got an object: " + o);
} catch (Exception e) {
e.printStackTrace();
} finally {
tfinished2.countDown();
}
}
};
q.setPaused(true);
println("Queue paused");
executor.execute(taker);
executor.execute(taker);
tstarted2.await();
// Pause to show workers pause too
Thread.sleep(100L);
println("Queue unpausing");
q.setPaused(false);
tfinished2.await();
// "Got an object" should show a delay of at least 100 ms.
}
private static void println(String s) {
System.out.println(System.currentTimeMillis() + " - " + s);
}
}
I have multiple threads of multiple types (Different classes). I want in case one of them throws an exception and dies to be replaced by another NEW thread. I am aware of the join thread function but how would I go about implementing them for 5 different type of threads such as in case type 1 thread dies is instantly replaced without having to wait for type 2 to die first.
This is some sample pseudo-code.
class1 implements runnable{
void run(){
try{
while(true){
repeat task
}
} catch(Exception e){
log error
}
}
}
class2 implements runnable{
void run(){
try{
while(true){
repeat task
}
} catch(Exception e){
log error
}
}
}
class3 implements runnable{
void run(){
try{
while(true){
repeat task
}
} catch(Exception e){
log error
}
}
}
public main(){
// start all threads .start()
}
I want in case one of them throws an exception and dies to be replaced by another NEW thread.
I don't quite understand why you can't do:
public void run() {
// only quit the loop if the thread is interrupted
while (!Thread.currentThread().isInterrupted()) {
try {
// do some stuff that might throw
repeat task;
} catch (Exception e) {
// recover from the throw here but then continue running
}
}
}
Why do you need to restart a NEW thread? Just because a task threw an exception doesn't mean that it is somehow corrupt and it needs a fresh one to work appropriately. If you are trying to catch all exceptions (including RuntimeException) then catch (Exception e) will do this. If you want to be really careful you can even catch Throwable in case there is a chance that Errors are being generated – this is relatively rare.
If you actually have multiple tasks (or really anytime you are dealing with threads), you should consider using the ExecutorService classes. See the Java tutorial.
// create a thread pool with 10 workers
ExecutorService threadPool = Executors.newFixedThreadPool(10);
// or you can create an open-ended thread pool
// ExecutorService threadPool = Executors.newCachedThreadPool();
// define your jobs somehow
threadPool.submit(new Class1());
threadPool.submit(new Class2());
...
// once we have submitted all jobs to the thread pool, it should be shutdown
threadPool.shutdown();
So instead of forking a thread to do multiple tasks, you start a thread pool and it starts threads as necessary to accomplish a bunch of tasks. If a task fails, you could certain submit another task to the pool although that's a slightly strange pattern.
If you want to wait for all of the tasks to finish you'd use:
threadPool.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
boolean shouldStop() {
// it's a good idea to think about how/when to stop ;)
return false;
}
void runThreadGivenType(final Runnable taskToRun) {
new Thread() {
#Override
public void run() {
try {
taskToRun.run();
} finally {
if (!shouldStop()) {
runThreadGivenType(taskToRun);
}
}
}
}.start();
}
public void main(String[] args) throws Exception {
runThreadGivenType(new Runnable() { public void run() { System.out.println("I'm almost immortal thread!"); throw new RuntimeException(); } });
TimeUnit.SECONDS.sleep(10);
}
and it's a good idea to think about executors to manage thread pools too. plain, [un/hand]-managed threads are not the best practice ;)
I have a task x that is executed continuously in a thread which will only stop when the boolean changes it's state to true. I have done some reading and there are 3 ways that I approach when killing threads that are in the code below. Which of the 3 methods is effective ? And if none of them aren't effective or correct kindly suggest a proper approach with some code for reference.
Below is the code :
public class MyTest {
private static class transaction {
private String param1,param2,param3, param4, param5;
public transaction (String param1,String param2,String param3,String param4,String param5){
this.param1=param1;
this.param2=param2;
this.param3=param3;
this.param4=param4;
this.param5=param5;
}
public String getParam1(){
return this.param1;
}
public String getParam2(){
return this.param2;
}
public String getParam3(){
return this.param3;
}
public String getParam4(){
return this.param4;
}
public String getParam5(){
return this.param5;
}
}
public static void processBatch(String workerName){
try{
java.util.List <transaction> transactions= new java.util.LinkedList<transaction>();
java.sql.ResultSet dbtrx=Database.db.execQuery((Object)"dbname.procname");
while(dbtrx.next()){// Takes a snapshot of the pending payments in the table and stores it into the list.
Object obj=new transaction (dbtrx.getString("col1"), dbtrx.getString("col2"), dbtrx.getString("col3"), dbtrx.getString("col4"), dbtrx.getString("col5"));
transactions.add((transaction)obj);
obj=null;
}
java.util.Iterator<transaction> iterate= transactions.iterator();
/* Processes the pending batch payments*/
while(iterate.hasNext()){
transaction trx=iterate.next();
/*Calls posting function here*/
System.out.println(workerName+":- Param1 : "+trx.getParam1()+" - Param2 : " +trx.getParam2()+
" - Param3 : "+ trx.getParam3()+" - Param4 : "+ trx.getParam4()+" - Param5 : "+ trx.getParam5());
iterate.remove();
}
/*cleaning object references*/
dbtrx=null;
transactions=null;
iterate=null;
}catch(Exception e){
e.printStackTrace();
}
}
public static void main(String [] args) throws InterruptedException{
volatile boolean stop=false;
Object hold= new Object();
new Thread("Batch Worker A"){
#Override
public void run(){
while(true){
if(stop!=true){
processBatch(Thread.currentThread().getName());
}else{
try{
Thread.sleep(0);
Thread.currentThread().interrupt();
}catch(java.lang.InterruptedException e){
Thread.currentThread().interrupt();
break;
}
}
}
}}.start();
new Thread("Batch Worker B"){
#Override
public void run(){
try{
while(stop!=true){
processBatch(Thread.currentThread().getName());
}
Thread.sleep(0);
Thread.currentThread().interrupt();
}catch(java.lang.InterruptedException e){
Thread.currentThread().interrupt();
}
}}.start();
new Thread("Batch Worker C"){
#Override
public void run(){
while(!Thread.currentThread().isInterrupted()){
if(stop!=true){
processBatch(Thread.currentThread().getName());
}else{
Thread.currentThread().interrupt();
}
}
}}.start();
}
}
}
The recommended approach is to use the thread's interrupted flag to signal the thread loop to terminate. There's no reason to use two flags (stopped and the interrupted flag) where one will do, and you don't seem to be using the interrupted flag for anything else.
See the Java tutorial subject Interrupts for a more extensive discussion and examples.
Why not simply this way:
new Thread("Batch Worker A"){
#Override
public void run() {
while(!stop){
processBatch(Thread.currentThread().getName());
}
}
}}.start();
Alternatively, use Thread.interrupt() like so:
new Thread("Batch Worker A"){
#Override
public void run() {
while(!interrupted()){
processBatch(Thread.currentThread().getName());
}
}
}}.start();
but then you need to keep reference to all the threads, and interrupt them all, so the boolean flag might be simpler (be sure to make it volatile).
In all of your examples, you aren't really killing the thread, you are stopping the batch from processing more items.
To understand the difference, note that none of your methods would actually stop the thread while the thread is within the processBatch function.
There are some things to take note of:
There is no point in calling Interrupt() on your current thread. The idea behind Interrupt is for external threads to call it. In your case, you can just as well throw an exception, or return from the run() function (which would shut down the thread automatically).
Even interrupt() can't in many situations stop a thread if that thread is locked outside java ,such as thread waiting for IO (if not using NIO), including a socket, which is what the database connection is, you'll need to design a different way to stop a thread inside IO (usually by doing a timeout, but there are other ways).
if you goal is simply to stop the next batch from happing use the code from Joonas :
new Thread("Batch Worker A"){
#Override
public void run() {
while(!stop){
processBatch(Thread.currentThread().getName());
}
}
}}.start();
if your goal is to interrupt the process while running the batch, you can just as well do:
public static void main(String[] args) {
var t =new Thread("Batch Worker A"){
#Override
public void run() {
processBatch(Thread.currentThread().getName());
}
}.start();
t.interrupt();
}
in general interrupt is the preferred method, and using a local scoped variable and anonymous classes is a really bad idea (use a static variable, or better an injected interface with a function to check if the thread should continue).