How to make a thread wait and execute another??? - java

I have two Threads classes "AddThread" and "ReadThread". The execution of these threads should be like this "AddThread should add 1 record and wait until ReadThread displays the record after that ReadThread should display that added record again AddThread should add another record" this process should continue untill all the records are added(REcords are accessed from LinkedList). Here is the code
class AddThread extends Thread
{
private Xml_Parse xParse;
LinkedList commonlist;
AddThread(LinkedList commonEmpList)
{
commonlist = commonEmpList;
}
public void run()
{
System.out.println("RUN");
xParse=new Xml_Parse();
LinkedList newList=xParse.xmlParse();
try
{
synchronized (this) {
if(newList.size()>0)
{
for(int i=0;i<newList.size();i++)
{
System.out.println("FOR");
commonlist.add(newList.get(i));
System.out.println("Added" +(i+1)+ "Record");
}
System.out.println(commonlist.size());
}
}
}
catch(Exception e)
{
}
}
}
class ReadThread extends Thread
{
LinkedList commonlist;
ReadThread(LinkedList commonEmpList)
{
commonlist = commonEmpList;
}
public void run()
{
try
{
synchronized (this) {
System.out.println();
System.out.println("ReadThread RUN");
sleep(1000);
//System.out.println("After waiting ReadThread RUN");
System.out.println(commonlist.size());
if(commonlist.size()>0)
{
for(int j=0;j<commonlist.size();j++)
{
System.out.println("Read For");
System.out.println("EmpNo: "+((EmployeeList)commonlist.get(j)).getEmpno());
System.out.println("EmpName: "+((EmployeeList)commonlist.get(j)).getEname());
System.out.println("EmpSal: "+((EmployeeList)commonlist.get(j)).getEmpsal());
}
}
}
}
catch(Exception e)
{
}
}
}
public class MainThread
{
public static LinkedList commonlist=new LinkedList();
public static void main(String args[])
{
AddThread addThread=new AddThread(commonlist);
ReadThread readThread=new ReadThread(commonlist);
addThread.start();
readThread.start();
}
}

You'll need to learn how to effectively use wait() and notify().
See also:
Guarded Blocks

What about using a BlockingQueue with a capacity of 1? Use offer instead of add so that producer thread is blocked.
You might also consider using a Semaphore with one permit, making it a mutex.

You use join() and yield() to control flux. If you want the current thread to stop and wait until the new thread finishes the work,
t1.run()
t.join()
when t1 finishes t continues.

Related

correct approach for 2 threads alternatively printing numbers

I have written a program which creates a 2 new thread and shares a common lock object to print numbers alternatively.
Wanted to know if the approach for using wait() and notify() is correct?
Main Class
public class MyMain {
public static void main(String[] args) {
MyThread1 obj = new MyThread1();
Thread thread1 = new Thread(obj);
Thread thread2 = new Thread(obj);
thread1.setName("t1");
thread2.setName("t2");
thread1.start();
thread2.start();
}
}
Thread Class
public class MyThread1 implements Runnable{
int i = 0;
#Override
public synchronized void run() {
while(i<10)
{
if(i%2==0)
{
try{
notify();
System.out.println(Thread.currentThread().getName()+" prints "+i);
i++;
wait();
}catch(Exception e){ e.printStackTrace(); }
}else
{
try{
notify();
System.out.println(Thread.currentThread().getName()+" prints "+i);
i++;
wait();
}catch(Exception e){ e.printStackTrace(); }
}
}
}
}
Can there be a better usage of wait() and notify() instead of using it in both the if conditions?
Since there you have some code repetition I'd just go with something like:
while(true) {
//If it's not my turn I'll wait.
if(i%2==0) wait();
// If I've reached this point is because:
// 1 it was my turn OR 2 someone waked me up (because it's my turn)
System.out.println(Thread.currentThread()": "+i);
i++; // Now is the other thread's turn
// So we wake him up
notify();
}
Also, be very careful with monitor's behaviour. (Thread waiting/notifying queues).

Make one thread wait for another to finish

I have two thread classes: one that prints numbers from 0 to 9, and another from 100 to 109. What I want is to make the first thread wait for the other one to finish. For this, I used the join() method, but it's not working. Please tell me where I'm going wrong:
//demonstrates the use of join() to wait for another thread to finish
class AThread implements Runnable {
Thread t;
AThread() {
t = new Thread(this);
}
public void run() {
try {
for (int i=0; i<10; i++) {
System.out.println(i);
Thread.sleep(10);
}
} catch (InterruptedException e) {
System.out.println(t + " interruped.");
}
}
public void halt(Thread th) {
try {
th.join();
} catch (InterruptedException e) {
System.out.println(t + " interruped.");
}
}
}
//a different thread class (we distinguish threads by their output)
class BThread implements Runnable {
Thread t;
BThread() {
t = new Thread(this);
}
public void run() {
try {
for (int i=100; i<110; i++) {
System.out.println(i);
Thread.sleep(10);
}
} catch (InterruptedException e) {
System.out.println(t + " interruped.");
}
}
}
public class WaitForThread {
public static void main(String[] args) {
AThread t1 = new AThread();
BThread t2 = new BThread();
t1.t.start();
t1.halt(t2.t); //wait for the 100-109 thread to finish
t2.t.start();
}
}
You call join on the thread before it has started. That doesn't work; in that case, join will return immediately, it's not going to wait until the other thread has started and stopped later. You can see this in the API documentation:
Thread.join()
This implementation uses a loop of this.wait calls conditioned on this.isAlive.
Thread.isAlive()
Tests if this thread is alive. A thread is alive if it has been started and has not yet died.
Reorder the statements in your main method
t1.t.start();
t2.t.start();
t1.halt(t2.t); //wait for the 100-109 thread to finish
edit to answer your questions in the comments:
If you want the thread in AThread to wait for the thread in BThread to finish before doing its job, then you'll need to call join in AThread.run, and change your main method:
class AThread implements Runnable {
Thread t;
Thread threadToWaitFor;
AThread(Thread threadToWaitFor) {
t = new Thread(this);
this.threadToWaitFor = threadToWaitFor;
}
public void run() {
// First wait for the other thread to finish
threadToWaitFor.join();
// ...
}
// ...
}
public class WaitForThread {
public static void main(String[] args) {
BThread t2 = new BThread();
AThread t1 = new AThread(t2.t);
t2.t.start();
t1.t.start();
}
}

wait for N-1 out of N threads to end, then issue an instruction for the last thread

So, i apologize for the title. It's quite hard to explain in one sentence what i would like to do if you have no idea on how it is called.
So assume i can only use primitive thread functions (wait, notify, no concurrent package)
The program has 3 threads, all of them are the same and are called by the main thread. They behave normally until one of the three get an exception and so it must wait for the end of the remaining 2 threads in order to start a recovery process.
I was thinking about a static variable but I'm not really sure about it, i would love to keep it as simple as possible.
Each thread starts at the same time.
I don't see any reason why you can't use a static variable like you suggest. Here's how I would do it with an inner class...
private static boolean running = true;
public void test26546397() {
while (true) {
Thread t1 = new Thread(new MyRunnable());
Thread t2 = new Thread(new MyRunnable());
Thread t3 = new Thread(new MyRunnable());
t1.start();
t2.start();
t3.start();
try {
t1.join();
t2.join();
t3.join();
} catch (InterruptedException ex) {
ex.printStackTrace();
}
running = true;
// Do recovery
}
}
public class MyRunnable implements Runnable {
#Override
public void run() {
while (running) {
try {
// doStuff
} catch (Exception ex) {
running = false;
}
}
}
}
I would of course replace the while (true) with something a little more suitable.
I think you need java.concurrent.CountdownLatch, however if the java.concurrent package is not available to you can code this yourself using Object.wait/notify and synchronized blocks.
The latch can then be decremented in a finally {} on each Thread, this will be run if the Thread completes, or an exception occurs.
Your main program then just needs to wait for count to become 0.
public class StackOverflow26546397 {
static class CountdownLatch {
private int count;
private Object monitor = new Object();
public CountdownLatch(int count) {
this.count = count;
}
public void countDown() {
synchronized (monitor) {
count--;
monitor.notifyAll();
}
}
public void await() throws InterruptedException {
synchronized (monitor) {
while (count > 0) {
monitor.wait();
}
}
}
}
static class Job implements Runnable {
private CountdownLatch latch;
public Job(CountdownLatch latch) {
this.latch = latch;
}
#Override
public void run() {
try {
// do work.
Thread.sleep((long) (Math.random() * 3000d));
} catch (InterruptedException e) {
//
} finally {
latch.countDown();
}
}
}
public static void main(String[] args) throws InterruptedException {
CountdownLatch latch = new CountdownLatch(3);
new Thread(new Job(latch)).start();
new Thread(new Job(latch)).start();
new Thread(new Job(latch)).start();
latch.await();
System.out.println("All threads finished");
}
}
Not sure what you are trying to do but this is as simple as I can think of (just native concurrency):
Create a static or shared volatile boolean
private static volatile boolean exceptionOccured=false
Set the above to 'true' when exception occurs:
....}catch(Exception e){
exceptionOccured=true;
}
Check this periodically in you normal thread flow:
if (exceptionOccured)
//enter you synchronized call here
the synchronized method could look something like:
public synchronized void checkAndRecover(){
//decrement a counter or other logic to identify which is the last Thread and then
//perform any recovery logic
}

How can I start a thread from another and restart a thread after execution?

I have 2 threads, the "main" thread which starts a secondary thread to run a little process.
The "main" thread must wait for the secondary thread for a few of seconds to complete the process, after that time, the "main" thread must start again no matter what happened with the process of the secondary thread.
If the secondary process ended earlier, the "main" thread must start to work again.
How can I start a thread from another, wait for the end of execution, and restart the thread after?
I have a code here, but the ExampleRun class, must wait, for example, 10 sec and start again, no matter what happend with MyProcess
public class ExampleRun {
public static void main(String[] args) {
MyProcess t = new MyProcess();
t.start();
synchronized (t) {
try {
t.wait();
} catch (InterruptedException e) {
System.out.println("Error");
}
}
}
}
public class MyProcess extends Thread {
public void run() {
System.out.println("start");
synchronized (this) {
for (int i = 0; i < 5; i++) {
try {
System.out.println("I sleep");
sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
flag = true;
System.out.println("Wake up");
notify();
}
}
}
The simplest way to achieve what you want is to use Thread.join(timeout).
Also, do not use synchronized, wait, or notify on Thread objects. This will interfere with the Thread.join implementation. See the documentation for details.
Here's what your main program would look like:
public static void main(String[] args) {
MyProcess t = new MyProcess();
t.start();
try {
t.join(10000L);
} catch (InterruptedException ie) {
System.out.println("interrupted");
}
System.out.println("Main thread resumes");
}
Note that when the main thread resumes after the join() call, it can't tell whether the child thread completed or whether the call timed out. To test this, call t.isAlive().
Your child thread of course could do anything, but it's important for it not to use synchronized, wait, or notify on itself. For example, here's a rewrite that avoids using these calls:
class MyProcess extends Thread {
public void run() {
System.out.println("MyProcess starts");
for (int i = 0; i < 5; i++) {
try {
System.out.println("MyProcess sleeps");
sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("MyProcess finishes");
}
}
You can do this with a simple lock method:
public static void main (String[] args)
{
// create new lock object
Object lock = new Object();
// create and start thread
Thread t = new Thread(() ->
{
// try to sleep 1 sec
try { Thread.sleep(1000); }
catch (InterruptedException e) { /* do something */ }
// notify main thread
synchronized (lock) { lock.notifyAll(); }
};
t.start();
// wait for second thread to finish
synchronized (lock)
{
while (t.isAlive())
lock.wait();
}
// second thread finished
System.out.println("second thread finished :)");
}
You could call Thread.join() on the Thread you want to wait for, per the Javadoc,
Waits for this thread to die.
Alternatively, you could use a Future and simply call get(), from its' Javadoc,
Waits if necessary for the computation to complete, and then retrieves its result.

Having troubles with threads and semaphors in JAVA

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.

Categories