thread stops unwantingly - java

I have a thread that is running and performing a task repeatedly. I've implemented a counter to show me the iterations of the task performed by the thread. Every now and then I see that the counter is stuck somewhere and it's not increasing anymore. I don't receive any error or exceptions. The application runs but it looks like the thread just stopped without me asking it.
I will add some code to show the thread execution:
notice the int "c" - thats the counter for iterations.
public void check() {
Thread check = new Thread() {
public void run() {
for (;;) {
EventQueue.invokeLater(new Runnable() {
public void run() {
// Update GUI here on EventQueue.
try {
Task.readTasks();
} catch (InvalidFormatException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (NoteInfo == null || NoteInfo == "") {
btnViewNote.setEnabled(false);
} else {
btnViewNote.setEnabled(true);
}
textField.setText(Task.printNextTask);
c++;
lblCycle.setText("Cycle: " + c);
}
});
try {
Thread.sleep(5000);
// Task.initializeIt();
} catch (InterruptedException ie) {
break;
}
if (killcheck)
break;
}
}
};
check.start();
}
public static void stopChecking() {
killcheck = true;
progressBar.setValue(0);
textArea.setText("");
textField.setText("");
c = 0;
lblCycle.setText("Cycle: " + c);
}

The check thread gets interrupted by another thread. Print the stack trace in the catch block and verify it.
try {
Thread.sleep(5000);
// Task.initializeIt();
} catch (InterruptedException ie) {
// break; // just ignore it
}

I don't see the definitions of killcheck or c but it is possible that these have not been marked as volatile?
If multiple threads are reading and writing a shared value then there must be some sort of synchronization otherwise they could be dealing with stale values. You can either use one of the atomic classes such as AtomicBoolean or AtomicInteger, use the synchronized keyword, or mark the variable as volatile. All three would allow the main thread and the inner thread to see each other's changes to the shared fields.
volatile int c;
volatile boolean killcheck;
For posterity, here's how you use the atomic classes:
final AtomicInteger c = new AtomicInteger();
final AtomicBoolean killcheck = new AtomicBoolean();
...
c.incrementAndGet();
...
if (killcheck)
break;
...
killcheck.set(true);
...
c.set(0);

Related

Producing and consuming into to list using threads?

I created two separate threads one for writing into a list and second for removing from the list.
package com.produ.consu;
public class Test {
public static void main(String[] args) {
Operations operations = new Operations();
Runnable r1 = new ThreadsClass(operations);
Runnable r2 = new ThreadsClass(operations);
Thread t1 = new Thread(r1);
Thread t2 = new Thread(r2);
t1.setName("READ");
t2.setName("WRITE");
t1.start();
t2.start();
}
}
Above is Test class where I created threads.
package com.produ.consu;
public class ThreadsClass implements Runnable {
Operations operations;
ThreadsClass(Operations operations){
this.operations=operations;
}
#Override
public void run() {
// TODO Auto-generated method stub
if(Thread.currentThread().getName().equals("WRITE")) {
operations.writeList();
}
else {
operations.readList();
}
}
}
Above is class calling synchronized methods based on the thread name:
import java.util.ArrayList;
import java.util.List;
public class Operations {
List<Integer> list=null;
int count=0;
boolean flag;
Operations(){
list=new ArrayList<>();
flag=true;
}
public synchronized void writeList() {
// TODO Auto-generated method stub
while(true) {
if(flag) {
count++;
list.add(count);
System.out.println("inise if block...."+Thread.currentThread().getName());
System.out.println(list);
flag=false;
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
else {
notify();
}
}
}
public synchronized void readList() {
// TODO Auto-generated method stub
while(true) {
if(!flag) {
Integer i = list.remove(0);
System.out.println(i+"..removed at index by"+Thread.currentThread().getName());
flag=true;
notify();
}
else {
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
Above is where I mentioned functionality.
So write thread hast to write element to list and wait until it is removed by the second thread.
Once removed second should notify 1st and wait for until element inserted.
But getting...
inise if block....WRITE [1]
Not even removed and it has to be a continuous process.
Give me suggestions on given code.
You should wait() inside the else block also, otherwise the while will continue to run if the if is not satisfied and the other thread won't get a chance to execute.
After the read/write operation is performed the thread should call notify to wake up the other thread and itself should go in the waiting state.
public synchronized void writeList() {
while (true) {
if (flag) {
count++;
list.add(count);
System.out.println("inise if block...." + Thread.currentThread().getName());
System.out.println(list);
flag = false;
try {
notify(); //notify the read thread that write is complete
wait(); // go into the waiting state so that no further write is done until the current element is removed by the read thread.
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
try {
wait(); //wait in else, otherwise while will run endlessly
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public synchronized void readList() {
while (true) {
System.out.println("in read");
if (!flag) {
Integer i = list.remove(0);
System.out.println(i + "..removed at index by" + Thread.currentThread().getName());
flag = true;
try {
notify(); //notify write thread that read is complete
wait(); //go into wait until new element is inserted
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
try {
wait(); //wait in else otherwise while runs endlessly
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
You should replace the method synchronization with more granular synchronization: wrap the operations that access the list and update count with a synchronized block.
Alternatively, use a linked blocking queue to pass “messages” between threads (or, in more advanced scenarios, a messaging solution such as Akka, Kafka, zeromq, or other similar solutions)
Since you only add one elemet at a time you could also use a Exchanger.
Take a look at the Java concurrent package.
import java.io.IOException;
import java.util.concurrent.Exchanger;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class Foo {
public static void main(String[] args) throws IOException, InterruptedException {
final Exchanger<Integer> exchanger = new Exchanger<>();
ExecutorService executorService = Executors.newCachedThreadPool();
executorService.execute(() -> {
// producer
int count = 0;
while (!Thread.currentThread().isInterrupted()) {
try {
exchanger.exchange(count++);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
});
executorService.execute(() -> {
// reader
while (!Thread.currentThread().isInterrupted()) {
try {
System.out.println("consume " + exchanger.exchange(null));
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
});
System.in.read();
executorService.shutdownNow();
executorService.awaitTermination(10, TimeUnit.SECONDS);
System.out.println("Shut down");
}
}

Print Even Odd number using two threads

I was trying to print even and odd numbers by two threads repetitively using wait and notify. However, I have gone through all the implementations given in website. Though as a first time Multi threading developer I was trying to do it my self, but I could not get the desired result. Here I am pasting my code below: Could you please review and revert back with the corrections and explanations where I made the mistake.
package com.test.printEvenOdd;
public class PrintOddEvenNumbers {
public static void main(String[] args){
String s = new String("");
EvenThread t1= new EvenThread(s);
OddThread t2= new OddThread(s);
Thread th1 = new Thread(t1);
Thread th2 = new Thread(t2);
th1.start();
th2.start();
}
}
class EvenThread implements Runnable{
String s;
EvenThread(String s){
this.s= s;
}
#Override
public void run() {
synchronized(s){
for(int i=1;i<=10;i++){
if(i%2==0){
try {
Thread.sleep(50);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(i);
s.notify();
}
try {
s.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
class OddThread implements Runnable{
String s;
OddThread(String s){
this.s= s;
}
#Override
public void run() {
synchronized(s){
for(int i=1;i<=10;i++){
try {
Thread.sleep(50);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(i%2==1){
System.out.println(i);
s.notify();
}
try {
s.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
Your problem is that you locking is too conservative/restrictive:
You put the lock around the whole loop; for both threads.
So, one thread gets into its loop; but quickly it can't progress. Because it would need that other thread to progress. But the second thread can't even start - because it can enter its loop at all!
In other words: in order to make progress; both threads need to be able to enter their respective loops; and make enough progress so that the other thread can do its next step.
Thats like building a room that only two person can exit together; but then you allow only one person to enter that room.
Welcome to multi-threaded programming; you just created your first dead-lock.
And for the record: when re-arranging the locks; make sure that you get the signaling right; so that wait/notify can work as supposed.
Finally: if you look carefully at your code; you will find that you duplicated a lot of code. That is always a bad idea. Instead: try to figure which parts are really different; and anything else ... should exist exactly once in your source code. So, as another exercise: when you re-arranged your code so that it does what it is supposed to do - try if you can refactor it, so that the amount of code duplication is minimized. I guarantee you, that will be an exercise worth spending your time on!
You should move the "wait()" inside the "if" block. Else thread will go in to wait without notifying the other waiting thread and both of them will be waiting.
if(i%2==0){
synchronized(s){
System.out.println(i);
try {
s.notify();
s.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
There are issues with the code. There is no need for sleep. As mentioned in previous response, you are synchronizing too eagerly which is unnecessary. There is no guarantee whether even thread will start first or odd thread will start first. It depends on whichever thread manages to acquire lock first. In the end, one thread will be waiting forever as the other thread would have come already come out and no one will notify after that. And any wait() code should handle spurious wakeup explained here
There are a number of issues with your initial code. See GhostCat's answer for explanations of them. In general, this sort of computation isn't great for multi threading since you are (apparently) wanting the numbers printed sequentially. But, given that desire and wanting to use 2 threads interleaving to do that, you could do it as follows. Note that there are still some problems with this solution. The thread depends on a different thread having executed to be able to reach it's own end condition which means that if you only created one for odd (or even) numbers, you'd go into an infinite loop.
import java.util.Objects;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.function.IntPredicate;
public class Foo {
public static void main(String[] args) {
// an executor service will handle the thread pool and scheduling
ExecutorService pool = Executors.newFixedThreadPool(2);
pool.submit(new NumberPrintAndIncrement(i -> i % 2 != 0));
pool.submit(new NumberPrintAndIncrement(i -> i % 2 == 0));
// you want to shut down the pool when the threads are done
pool.shutdown();
}
}
final class NumberPrintAndIncrement implements Runnable {
// Need a shared lock for accessing and updating the current number
private static final Object LOCK = new Object();
// The number is shared between threads so it needs to be volatile
private static volatile int number = 1;
// Instance variable for letting a particular runnable know if it should
// print the number in it's current state
private final IntPredicate predicate;
NumberPrintAndIncrement(IntPredicate predicate) {
this.predicate = Objects.requireNonNull(predicate);
}
#Override
public void run() {
while (number < 10) {
// this could run at any point and any number of times, but
// that doesn't matter since it is just doing a quick check and
// a possible update. If the number doesn't satisfy the predicate,
// this will just be a no-op. Having a predicate means
// you don't have to rely on wait and notify to try and
// achieve interleaving the number output properly which
// is good due to the liveness problem Rajesh mentioned.
synchronized (LOCK) {
if (predicate.test(number)) {
System.out.println(number);
number++;
}
}
}
}
}
To understand what's happening a bit better, let's go through the steps happening in each Thread.
public class PrintOddEvenNumbers {
public static void main(String[] args){
String s = new String("");
EvenThread t1= new EvenThread(s);
OddThread t2= new OddThread(s);
Thread th1 = new Thread(t1);
Thread th2 = new Thread(t2);
th1.start();
th2.start();
}
}
class EvenThread implements Runnable{
String s;
EvenThread(String s){
this.s= s;
}
#Override
public void run() {
synchronized(s){
for(int i=1;i<=10;i++){
System.out.println("EvenThread i: " + i);
if(i%2==0){
try {
Thread.sleep(50);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(i);
System.out.println("EvenThread notify");
s.notify();
}
try {
System.out.println("EvenThread waiting..");
s.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
class OddThread implements Runnable{
String s;
OddThread(String s){
this.s= s;
}
#Override
public void run() {
synchronized(s){
for(int i=1;i<=10;i++){
System.out.println("OddThread i: " + i);
try {
Thread.sleep(50);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(i%2==1){
System.out.println(i);
System.out.println("OddThread notify");
s.notify();
}
try {
System.out.println("OddThread waiting..");
s.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
This will print:
EvenThread i: 1
EvenThread waiting..
OddThread i: 1
1
OddThread notify
OddThread waiting..
EvenThread i: 2
2
EvenThread notify
EvenThread waiting..
OddThread i: 2
OddThread waiting..
A simple explanation:
When OddThread reaches of i of 2, it waits for s to be released.
When EvenThread reaches i of 2, it also waits for s to be released.
You now have both threads waiting to be woken up (deadlock).
This happens because of the conditions that need to be met in order to wake the other waiting thread up using notify i.e. i%2==1 and i%2=0.
This isn't the only problem however, there are also some fundamental issues.
The usage of Threads in this particular case if it were in production is incorrect as you're trying to do sequential work anyway, so the overhead of creating Threads for each task adds unnecessary overhead.
There is no resource being shared, making synchornize redundant.
You expect that one Thread will get a hold of a lock before the other, this isn't how Thread's work - it can be either one that gets a hold of the lock first.

Make even and odd threads to print numbers in natural order in Java

I know this question has been asked before, But I am unable to figure out why my solution is not working for me. I have two threads even and odd, one prints even numbers and other prints odd numbers. When I start the threads I want the output to be in natural order of numbers like 0 1 2 3..etc. This is my code:-
[updated]
public class ThreadCommunication {
public static void main(String... args) throws InterruptedException
{
final ThreadCommunication obj = new ThreadCommunication();
Thread even = new Thread(){
#Override
public void run()
{
for(int i=0;i<10;i=i+2){
synchronized(obj){
System.out.println(i);
try {
obj.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
};
Thread odd = new Thread(){
#Override
public void run()
{
for(int i=1;i<10;i=i+2){
synchronized(obj){
System.out.println(i);
obj.notify();
}
}
}
};
even.start();
odd.start();
}
}
when I run the above code, sometimes it prints the numbers in natural order as expected but sometimes it prints in some other order for ex:
0
1
3
5
7
9
2
What am I doing wrong here?
Edit:
volatile static boolean isAlreadyWaiting = false;
Thread even = new Thread() {
#Override
public void run() {
synchronized (obj) {
for (int i = 0; i < 10; i = i + 2) {
System.out.println(i);
try {
if (!isAlreadyWaiting) {
isAlreadyWaiting = true;
obj.wait();
}
obj.notify();
isAlreadyWaiting=false;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
};
Thread odd = new Thread() {
#Override
public void run() {
synchronized (obj) {
for (int i = 1; i < 10; i = i + 2) {
System.out.println(i);
try {
if(isAlreadyWaiting){
obj.notify();
isAlreadyWaiting = false;
}
if (!isAlreadyWaiting) {
isAlreadyWaiting = true;
obj.wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
};
Check documentation
public class IllegalMonitorStateException extends RuntimeException
Thrown to indicate that a thread has attempted to wait on an object's
monitor or to notify other threads waiting on an object's monitor
without owning the specified monitor.
Monitor is owned by obj
So you should call
obj.wait();
and
obj.notify();
For more info on Ownership
This methods (wait or notify) should only be called by a thread that
is the owner of this object's monitor. A thread becomes the owner of
the object's monitor in one of three ways:
By executing a synchronized instance method of that object.
By executing the body of a synchronized statement that synchronizes
on the object.
For objects of type Class, by executing a synchronized static method
of that class.
Only one thread at a time can own an object's monitor.
#Pragnani Kinnera is right about the exception you're seeing. But if you want to alternate between even and odd, you'll need to move your second synchronized block into the loop. Otherwise, the notifying thread will hold the lock exclusively until the loop completes. (As opposed to the first thread, which yields its lock on each round.)
Thread odd = new Thread(){
#Override
public void run()
{
for(int i=1;i<10;i=i+2){
synchronized(obj){
System.out.println(i);
notify();
}
}
}
};
The first thread, however, should have the loop inside the synchronized block. If both threads release the lock, they both have an equal chance at reacquiring it. But if the first loop is inside the synchronized block, the second thread won't be able to reenter until the first has completed a full round and is waiting once again.
EDIT: This still won't work correctly, because there is no guarantee that the first thread won't reacquire the lock before the second thread does, per this quote from the documentation:
The awakened thread will compete in the usual manner with any other threads that might be actively competing to synchronize on this object; for example, the awakened thread enjoys no reliable privilege or disadvantage in being the next thread to lock this object.
You'll probably want to wake and notify from both threads to ensure they're in sync.
Here is your solution:
public class ThreadCommunication {
public static void main(String args[]) throws InterruptedException
{
final ThreadCommunication obj = new ThreadCommunication();
Thread even = new Thread("Even Thread"){
#Override
public void run()
{
for(int i=0;i<10;i=i+2){
System.out.println(i);
synchronized(obj){
obj.notify();
}
synchronized(obj){
try {
obj.wait();
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
};
Thread odd = new Thread(){
#Override
public void run()
{
for(int i=1;i<10;i=i+2){
try {
synchronized(obj){
obj.wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(i);
synchronized(obj){
obj.notifyAll();
}
}
}
};
even.start();
odd.start();
}
}
As explained by #shmosel, your synchronized block should only contain code that need to be synchronized.

How to use InterruptedException effectively

Given code is working in doInBackground(). Where while loop is always true but i don't know how it calls other methods in catch.
Can someone explain me the technique and how can we benefit with this technique. I don't know how and when we get out of the loop.
doInBackground
if(isRunning)
{
while (true) //this loop should run always.
{
try
{
Thread.sleep(1L);
}
catch (InterruptedException ex)
{
Log.e("Testing Interuption", "error=" + ex.getMessage());
// some working here is also running
}
}
}
Can it call any statement after while or not? I mean can it also get out of while loop or not.
Edit
When did the Interuption Occur.It means when another AsyncTask is calling Thread.sleep(); it will interupt(means go to catch). Am I right?
I am calling Multiple AsyncTasks to set a CameraPreview using Bitmap.
#TargetApi(11)
public void start()
{
if (Build.VERSION.SDK_INT >= 11)
{
executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, new Void[0]);
return;
}
execute(new Void[0]);
}
The while (true) statement will never end, since there's nothing to break out of the loop, so no, it can not get out of the while loop. (Depends on what's in // some working here is also running though.)
The code in the catch statement is executed if another thread sends an interrupt to this thread. When the code has been executed under catch the while loop re-starts again.
If you want to break out of the while loop if an InterruptedException is received, add a break; statement inside the catch.
It can call anything, as long as you break out of your loop, like this:
if (isRunning) {
while (true) //this loop should run always.
{
try {
Thread.sleep(1L);
}
catch (InterruptedException ex) {
Log.e("Testing Interuption", "error=" + ex.getMessage());
// some working here is also running
break; // <--
}
}
doStuffAfterWhileLoop();
}
i wrote some code, which should help you to understand how it is working.
public class Test2 {
boolean doBreakOut = false;
public Test2() {
Runnable runnable = new Runnable() {
#Override
public void run() {
while (true) // this loop is running while
// !(doBreakOut == true && isInterrupted()).
{
try {
Thread.sleep(1L);
} catch (InterruptedException ex) {
// this is executed when interrupt() is called.
if (doBreakOut) {
break;
}
System.out.println(("Testing Interuption -> "
+ "error=" + ex.getMessage()));
}
}
System.out
.println("did leave loop, threat will shut down now.");
}
};
try {
Thread threat = new Thread(runnable);
threat.start();
// Thread.sleep(x) makes the main thread wait for x milliseconds
Thread.sleep(2000);
threat.interrupt();
Thread.sleep(2000);
threat.interrupt();
Thread.sleep(2000);
doBreakOut = true;
threat.interrupt();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
new Test2();
}
}

How to stop the printing in thread A from thread B?

I have written some Java code, which will call a C interrupt handler.
In Java thread A, I use waitFor() to wait the interrupt coming and then execute reboot.
In Java thread B, I will loop printing a counter value and sleep several milliseconds.
And I hope when I detect the interrupt, and then stop the printing in thread B at once, but failed. In fact, the system detects the interrupt in time, but the printing continues for maybe 10 seconds and then reboot. Note: reboot occurs maybe 11 seconds after the interrupt(press a button), the hardware is not fast.
Below is my code, any suggestion? Thanks!
import java.io.IOException;
class ThreadTesterA implements Runnable
{
private int counter;
private String cmds[] = new String[1];
private Process pcs;
#Override
public void run()
{
cmds[0] = "./gpio-interrupt";
try {
pcs = Runtime.getRuntime().exec(cmds);
if(pcs.waitFor() != 0) {
System.out.println("error");
} else {
ThreadTesterB.setClosed(true);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
class ThreadTesterB implements Runnable
{
private int i;
private static boolean closed=false;
public static void setClosed(boolean closed)
{
closed = closed;
}
#Override
public void run()
{
// replace it with what you need to do
while (!closed) {
System.out.println("i = " + i);
i++;
try {
Thread.sleep(20);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println();
}
}
public class ThreadTester
{
public static void main(String[] args) throws InterruptedException
{
Thread t1 = new Thread(new ThreadTesterA());
Thread t2 = new Thread(new ThreadTesterB());
t1.start();
t1.setPriority(Thread.MAX_PRIORITY);
//t1.join(); // wait t1 to be finished
t2.start();
//t2.join();
}
}
You're writing and reading a boolean variable (closed) from 2 different threads without any kind of synchronization. There is thus no guarantee that what you wrote in one thread is visible in the other thread. You need to either
make the boolean variable volatile
access the boolean variable (writing and reading) using blocks or methods synchronized on the same lock
use an AtomicBoolean instead of a boolean
I would use the third solution.

Categories

Resources