I have written a program to understand wait() and notify() methods. But when I run the program it hangs and nothing happens. Basically I want one thread (ThreadDemo) to complete its execution (display its output) thereafter other thread should display its output (ThreadDemo2).
As wait and notify requires the use of same object I have created common class LogicClass.
Can you please point out what is the problem in my code? I have to use these concepts in my project.
Program Link
In the code, I noted at least two problems:
Your main function does not wait for the child threads to join and so will exit. Use Thread::join.
You never call show() function that includes the notifyAll.
Pretty sure that non-daemon threads will not exit when the main thread exits.
I'd recommend using java.util.concurrent package if at all possible. It makes multithreading less error prone. You are missing for example a missed notification guard that can cause eternal waiting. If you were to use a latch it would solve that problem.
** EDIT
Sorry I should say your existing missed notification guard (value in LogicClass) can have cases where it doesn't function correctly - the while loops before the wait or notify aren't sufficient to guarantee which thread "wins the race" to the monitor.
I made a comment earlier about making the code shorter while still demonstrating the same behaviour. You can see one thread is running show, the other display
class ThreadMain {
public static void main(String[] args) {
final LogicClass lg = new LogicClass(true);
new Thread(new Runnable() {
public void run() {
System.out.println("In threadDemo run method");
lg.show(10);
}
}).start();
new Thread(new Runnable() {
public void run() {
System.out.println("In thread2 run method");
lg.display(5);
}
}).start();
System.out.println("Hi, in main");
}
}
class LogicClass {
boolean value;
public LogicClass(boolean value) {
this.value = value;
}
synchronized void show(int a) {
if (value) {
for (; a != 0; a--)
System.out.println("This Output should come first");
value = false;
notifyAll();
}
}
synchronized void display(int a) {
while (value) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
for (; a != 0; a--)
System.out.println("This should come later");
}
}
Related
I'm having an issue synchronizing functions on the same object. In my main class, I have a button that when pressed, should fire two functions sequentially from a different class. The first thread runs fine. I'm thinking the second is getting caught in a deadlock, but idk how. However, when I specify a timeout for the second thread, it fires. Can somebody help me understand what's going on with the notify/wait?
public void actionPerformed(ActionEvent ae)
{
t = new Thread ()
{
public void run ()
{
synchronized(this)
{
one();
notify();
}
}
};
thr = new Thread ()
{
public void run ()
{
synchronized (this)
{
try
{
wait();
two();
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
};
thr.start();
t.start();
}
I'm having an issue synchronizing functions on the same object
Problem is that you are not synchronizing on same object/lock because this in each of synchronized(this) is referring to different instances of Thread:
one from t
one from thr
To avoid such problem create explicit lock Object which you will pass to your threads.
It's a race condition whether t or thr enters the synchronized section first. t could notify before thr waits.
I have a class which processes something. I'm trying to run a number of instances of this class in parallel.
However, I'm not sure if in TaskManager.startAll(), when I call r.go(), whether this would cause r to start running in its own thread, or within the main thread?
The total execution time that I'm getting seems to be very high, and despite my attempts at optimizing, nothing seems to be having any effect. Also, if I run a profiler on my project in Netbeans, it shows all the threads as sleeping. So I'd like to know if I'm doing something wrong?
This is the structure of the class:
public class TaskRunner implements Runnable {
private boolean isRunning = false;
public void run() {
while(true) {
while (! running) {
try {
Thread.sleep(1);
} catch (Exception e) {
e.printStackTrace();
}
}
process();
}
}
public void go() {
isRunning = true;
}
public void stop() {
isRunning = false;
}
private void process() {
//Do some number crunching and processing here
}
}
Here's how these are being run / managed:
public class TaskManager {
private ArrayList<TaskRunner> runners = new ArrayList<>();
public TaskManager() {
for (int i = 0; i < 10; i++) {
TaskRunner r = new TaskRunner();
new Thread(r).start();
runners.add(r);
}
}
public void startAll() {
for (TaskRunner r : runners) {
r.go();
}
}
}
Indeed, you are not "doing it right." If you want to create a multi-threaded Java application, the place to start is with the java.util.concurrent package.
It appears from your code that you want to run ten tasks in parallel. I assume that after "number crunching and processing," you'll want to aggregate the results and do something with them in the main thread. For this, the invokeAll() method of ExecutorService works well.
First, implement Callable to do the work you show in your process() method.
final class YourTask implements Callable<YourResults> {
private final YourInput input;
YourTask(YourInput input) {
this.input = input;
}
#Override
public YourResults call()
throws Exception
{
/* Do some number crunching and processing here. */
return new YourResults(...);
}
}
Then create your tasks and run them. This would take the place of your main() method:
Collection<Callable<YourResults>> tasks = new List<>(inputs.size());
for (YourInput i : inputs)
tasks.add(new YourTask(i));
ExecutorService workers = Executors.newFixedThreadPool(10);
/* The next call blocks while the worker threads complete all tasks. */
List<Future<YourResult>> results = workers.invokeAll(tasks);
workers.shutdown();
for (Future<YourResult> f : results) {
YourResult r = f.get();
/* Do whatever it is you do with the results. */
...
}
However, I'm not sure if in TaskManager.startAll(), when I call r.go(), whether this would cause r to start running in its own thread, or within the main thread?
So my first comment is that you should make isRunning be volatile since it is being shared between threads. If the threads are not starting when it goes to true (or seem to be delayed in starting) then I suspect that's your problem. volatile provides memory synchronization between the threads so the thread that calls go() and makes a change to isRunning will be seen immediately by the thread waiting for the change.
Instead of spinning like this, I would use wait/notify:
// this synchronizes on the instance of `TaskRunner`
synchronized (this) {
// always do your wait in a while loop to protect against spurious wakeups
while (!isRunning && !Thread.currentThread().isInterrupted()) {
try {
// wait until the notify is called on this object
this.wait();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
e.printStackTrace();
}
}
Then in the go() method you should do the following. stop() would be similar.
public void go() {
synchronized (this) {
isRunning = true;
this.notifyAll();
}
}
Notice that you should handle thread interrupts carefully. Test for isInterrupted() in the while running loop and re-interrupt a thread when InterruptedException is thrown is always a good pattern.
The total execution time that I'm getting seems to be very high, and despite my attempts at optimizing, nothing seems to be having any effect. Also, if I run a profiler on my project in Netbeans, it shows all the threads as sleeping.
So although the threads are mostly sleeping, they are still each looping 1000 times a second because of your Thread.sleep(1). If you increased the time sleeping (after making isRunning be volatile) they would loop less but the right mechanism is to use the wait/notify to signal the thread.
Awful solution, terrible. first I highly recommend you start reading some tutorial like [this]
Second, if threads should wait for a signal to go for some job, so why just don't you wait them!!!!!, something like this
import java.util.ArrayList;
public class TaskManager
{
//////////////////////
public volatile static Signal wait=new Signal();
//////////////////////
private ArrayList<TaskRunner> runners = new ArrayList<>();
public TaskManager()
{
for (int i = 0; i < 10; i++)
{
TaskRunner r = new TaskRunner();
new Thread(r).start();
runners.add(r);
}
try {
Thread.sleep(1000);
startAll();
Thread.sleep(1000);
pauseAll();
Thread.sleep(1000);
startAll();
Thread.sleep(1000);
haltAll();System.out.println("DONE!");
}catch(Exception ex){}
}
public void startAll()
{
synchronized(wait){
wait.setRun(true);;
wait.notifyAll();
}
}
public void pauseAll(){
wait.setRun(false);
}
public void haltAll(){
for(TaskRunner tx:runners){tx.halt();}
}
public static void main(String[] args) {
new TaskManager();
}
}
class TaskRunner implements Runnable
{
private Thread thisThread;
private volatile boolean run=true;
public void run()
{
thisThread=Thread.currentThread();
while(run){
if(!TaskManager.wait.isRun()){
synchronized(TaskManager.wait)
{
if(!TaskManager.wait.isRun()){
System.out.println("Wait!...");
try
{
TaskManager.wait.wait();
}
catch (Exception e)
{
e.printStackTrace();
break;
}
}
}}
process();
}
}
private double r=Math.random();
private void process(){System.out.println(r);try {
Thread.sleep(10);
} catch (Exception e) {
// TODO: handle exception
}}
public void halt(){run=false;thisThread.interrupt();}
}
class Signal{
private boolean run=false;
public boolean isRun() {
return run;
}
public void setRun(boolean run) {
this.run = run;
}
}
in above sample, all runners works till the Signal run boolean is true, and simple TaskManager class set tit as false for every time it needs to pause the threads. and about the halt, it just set the shutdown(run) flag to false, and also interrupt the thread because of if thread is in wait state.
I hope I could prove your solution is like dream-on story, and also could explained enough about my solution.
have a good parallel application :)
If these methods are called from two different threads at the same time, what will be the result?
public class FirstWord {
public static synchronized void writeFirstWord(boolean fromSecondWord) throws Exception {
if(fromSecondWord == false)
SecondWord.writeSecondWord();
System.out.print("Redflex"); }}
public class SecondWord {
public static synchronized void writeSecondWord() throws Exception {
Thread.sleep(100);
FirstWord.writeFirstWord(true);
System.out.print(" Traffic Systems"); }}
Deadlock is very likely in the code sample you have - if you have 2 threads, say ThreadA and ThreadB, then given this scenario:
ThreadA calls FirstWord.writeFirstWord(false) and the thread pauses once inside
ThreadB calls SecondWord.writeSecondWord() and the thread pauses once inside
Now ThreadA continues it'll stop at SecondWord.writeSecondWord(); as ThreadB has the lock SecondWord.
ThreadB can't continue because ThreadA has the lock on FirstWord.
The result is a deadlock.
Note that this isn't the only possible outcome of this code - depending on timing etc the code may run just fine for a while, but its very likely that you'll hit a deadlock at some point.
The result is unpredictable due to the unpredictable nature of sleep().
Also, it depends on how many cores there are, and what parameter you provide in the writeFirstWord(boolean) call.
I'll leave it to you to figure out the details :-)
Hint: one possibility is deadlock.
Example SSCCE (modified):
public class ThreadTest {
public static void main(String[] args) {
new Thread() {
public void run() {
try {
FirstWord.writeFirstWord(false);
} catch (Exception e) {
e.printStackTrace();
}
}
}.start();
new Thread() {
public void run() {
try {
SecondWord.writeSecondWord(false);
} catch (Exception e) {
e.printStackTrace();
}
}
}.start();
}
}
class FirstWord {
public static synchronized void writeFirstWord(boolean fromSecondWord) throws Exception {
System.out.println("FirstWord start");
Thread.sleep(100);
if (!fromSecondWord) SecondWord.writeSecondWord(true);
System.out.println("FirstWord end");
}
}
class SecondWord {
public static synchronized void writeSecondWord(boolean fromFirstWord) throws Exception {
System.out.println("SecondWord start");
Thread.sleep(100);
if (!fromFirstWord) FirstWord.writeFirstWord(true);
System.out.println("SecondWord end");
}
}
As you can see the console shows:
FirstWord start
SecondWord start
The first thread "enters" into the FirstWord synchronized block while the second one enters the SecondWord one. Then, after sleeping a little bit, the first thread tries to enter into the SecondWord method, and has to wait because the second thread has the lock for that method.
While this happens, the second thread is also waiting to get the other lock, and that's why both threads block and never reach the "end", as they never get both locks.
If you remove Thread.sleep in both methods it may work. As said, it is unpredictable. You can't know which thread is going to enter first.
package com.blt;
public class ThreadsExample implements Runnable {
public static void main(String args[]) {
Thread t=new Thread(new ThreadsExample());
Thread t1=new Thread(new ThreadsExample());
t.start();
t1.start();
}
public void run() {
try {
writeSecondWord();
}
catch(Exception e) {
e.printStackTrace();
}
}
public static synchronized void writeSecondWord() throws Exception {
Thread.sleep(100);
writeFirstWord(true);
System.out.print(" Traffic Systems");
}
public static synchronized void writeFirstWord(boolean fromSecondWord) throws Exception {
if(fromSecondWord == false)
writeSecondWord();
System.out.print("Redflex");
}
}
Output is: Redflex Traffic SystemsRedflex Traffic Systems
Running is above code is fine but there are fair chances that code will produce deadlock at some point of time.
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).
I have two classes. In class A, I have the run() method looped forever, while in the class B, i have the threadpool.
My question is, From Class B, how can I control and stop the thread executing run() method in class A , I have tried forceshutdown, threadExecutor.shutdownNow(), But it isnt working.
The loop seems to go on forever.
Here is example piece of code:
public class A implements Runnable {
public void run() {
while (true) {
System.out.println("Hi");
}
}
}
public class B {
public static void main(String[] args) {
int noOfThreads = 1;
A ThreadTaskOne = new A();
System.out.println("Threads are being started from Class B");
ExecutorService threadExecutor = Executors.newFixedThreadPool(noOfThreads);
threadExecutor.execute(ThreadTaskOne);
threadExecutor.shutdownNow();
System.out.println("B Ends, no of threads that are alive : " + Thread.activeCount());
}
}
As #MadProgammer said, your "infinite" loop needs to pay attention to Thread.isInterrupted. e.g. (very schematic)
public void run() {
while (!Thread.isInterrupted()) {
doSomethinginTheLoop1();
blah...blah...blah
// if the loop is very long you might want to check isInterrupted
// multiple times for quicker termination response
doSomethingInTheLoop2();
}
// now, here's a decision of what you do
// do you throw an InterruptedException or trust others to check interrupted flag.
// read Java COncurrency in Practice or similar...
}
The documentation on ExecutorService#shutdownNow() says -
There are no guarantees beyond best-effort attempts to stop processing actively executing tasks. For example, typical implementations will cancel via Thread.interrupt(), so any task that fails to respond to interrupts may never terminate.
And your thread doesn't seem to care if it has been interrupted.
So check if it has been interrupted
while (Thread.currentThread().isInterrupted())
instead of just doing
while (true)
May be below is useful for you.
public static class A implements Runnable {
public void run() {
while (!Thread.currentThread().isInterrupted()) {
System.out.println("Hi");
}
}
}