safe way to stop a thread in java - java

public class thread extends Thread {
static volatile boolean done = false;// volatile keyword is used
#Override
public void run() {
while (!done) {
for (int i = 1; i < 10; i++) {
try {
thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(currentThread());
System.out.println("1st thread>> " + i);
}
}
}
public static void main(String[] args) throws InterruptedException {
Thread th = new Thread(new thread(),"mythread");
th.start();
for (int i = 1; i < 10; i++) {
thread.sleep(400);
System.out.println(currentThread());
System.out.println("2nd thread>> " + i);
if (i == 4) {
done = true;// safe way to stop a thread
break;
}
}
}
}
I am using volatile static variable here.Is it a safe way to stop a thread and also
when I print currentThread() method I get the output like Thread[mythread,5,main]
what does the 5 and main refer to??

It's a safe way to stop a thread, but there is no reason for the variable to be static: you want to stop one thread, not all threads of the same class.
Moreover, there is a more standard and less fragile way to stop a thread: interrupting it.
public void run() {
while (!Thread.currentThread().isInterrupted() {
...
}
}
...
th.interrupt();
This has the additional advantage that a thread which is sleeping or waiting, or blocked in an interruptible IO method will be woken up with an InterruptedException. When such an exception happens, it means that the thread should stop running, so you shouldn't swallow the exception as you did. Instead, you should return from the run method as fast as possible:
try {
thread.sleep(200);
}
catch (InterruptedException e) {
return;
}

Thread to toString, which is what is being called when you do System.out.println(currentThread()) prints out the thread name, priority, and thread group.
I'm assuming you are trying to interrupt the thread for something other then a normal completion, so why not just use Thread.interrupt() and Thread.isInterrupted()?

Related

Does lock.notify() gets executed only at the end of the loop in a thread

public class MyVisibility {
private static int count = 0;
private static Object lock = new Object();
public static void main(String[] args) {
new MyVisibility.thread1().start();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
return;
}
new MyVisibility.thread2().start();
}
static class thread1 extends Thread {
int i = 0;
#Override
public void run() {
super.run();
while (true) {
synchronized (lock) {
count++;
System.out.println("Thread one count is " + count);
try {
lock.wait();
System.out.println("i am notified");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if (count > 5) {
return;
}
}
}
}
static class thread2 extends Thread {
int i = 10;
#Override
public void run() {
super.run();
while (true) {
synchronized (lock) {
count++;
System.out.println("Thead 2 count is " + count);
lock.notify();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if (count > 10) {
return;
}
}
}
}
}
In above code,
Current result on execution : I can see lock.notify() is getting called only after end of the while loop.
My assumption is Since lock.notify() is getting called immediately after count variable getting incremented, and immediately it should notify the waiting thread to resume its execution, instead after second thread completion of execution call is going for waiting thread to resume, what is the reason for this, can someone correct me what was wrong with my understanding.
Thank you.
Your deduction - "I can see lock.notify() is getting called only after end of the while loop" is not entirely correct. Try running multiple times, or put break point just after synchronized block of thread2, and then you will see thread1 "i am notified" being printed.
From documentation of notify() -
The awakened thread will not be able to proceed until the current
thread relinquishes the lock on this object
In your case before thread2 relinquishes lock and then thread1 acquires lock, thread2 acquires lock again by going into synchronized block.

Java - Synchronized block not working

I have the following class
public class OddPrinter implements Runnable {
public void run() {
try {
for (int n = 0; n <= 10; n++) {
if((n%2) != 0)
System.out.println(" Odd Thread" + n);
Thread.sleep(1000);
}
System.out.println("Exiting Odd Thread");
}
catch(InterruptedException e)
{
e.printStackTrace();
}
}
}
And the main class which tries to have a synchronized access to the object of the above class
public class MultiThread {
public static void main(String[] args) {
Thread t1, t2;
OddPrinter first = new OddPrinter();
synchronized(first)
{
t1 = new Thread(first, "firstThread");
t1.start();
t2 = new Thread(first, "secondThread");
t2.start();
}
}
}
I am getting an output as follows
Odd Thread1
Odd Thread1
Odd Thread3
Odd Thread3
Odd Thread5
Odd Thread5
Odd Thread7
Odd Thread7
Odd Thread9
Odd Thread9
Exiting Odd Thread
Exiting Odd Thread
A synchronized block ensures
that a call to a method that is a member of object occurs only after the current thread has
successfully entered object’s monitor.
According to the above reference ( Java2 - The Complete Reference - Herbert Schildt), I am expecting an output where one thread waits for the other to finish the printing of the odd numbers. But that is not happening. What is the issue here?
A synchronized block ensures that a call to a method that is a member of object occurs only after the current thread has successfully entered object’s monitor.
No it doesn't. It ensures that a synchronized method that is an instance member of the class of the object occurs only after the current thread has exited the block, if invoked on the same object, and that another synchronized block on the same object doesn't execute until this block exits.
Several of those conditions don't apply to your code.
I am expecting an output where one thread waits for the other to finish the printing of the odd numbers.
Wait for thread t1 to complete before starting thread t2:
t1.start():
t1.join();
t2.start();
You only synchronized one access. The other threads don't synchronize on the object, so nothing is blocked. Even if they did and were, once both threads have started, the code block in main completes and the threads are free to run anyway.
Furthermore, the synchronization you used in main happens in advance of any other threads that might conflict, and the main thread doesn't need any shared state in the first place, so the synchronization there is useless.
Study the concepts "critical section", "memory barrier", and Java's "happens-before". Buy and study the book Java Concurrency in Practice, by Brian Goetz, et al.
synchronized lock should be put inside your runnable code, not your main method.
I think you can either put synchronize to your method
public class OddPrinter implements Runnable {
public synchronized void run() {
try {
for (int n = 0; n <= 10; n++) {
if((n%2) != 0)
System.out.println(" Odd Thread" + n);
Thread.sleep(1000);
}
System.out.println("Exiting Odd Thread");
}
catch(InterruptedException e)
{
e.printStackTrace();
}
}
}
Or, you can put it in your method like this
public class OddPrinter implements Runnable {
static Object lock;
public void run() {
synchronized (lock) {
try {
for (int n = 0; n <= 10; n++) {
if((n%2) != 0)
System.out.println(" Odd Thread" + n);
Thread.sleep(1000);
}
System.out.println("Exiting Odd Thread");
}
catch(InterruptedException e)
{
e.printStackTrace();
}
}
}
}
You need to change OddPrinter where you can put synchronized block and use a single lock to synchronized so at time one thread can enter to critical section.And remove the synchronized block from main method.
public class OddPrinter implements Runnable {
private Object lock;
public OddPrinter(Object lock) {
this.lock = lock;
}
public void run() {
synchronized (lock) {
for (int n = 0; n <= 10; n++) {
if ((n % 2) != 0)
System.out.println(" Odd Thread" + n);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("Exiting Odd Thread");
}
}
}
public class MultiThread {
public static void main(String[] args) {
Thread t1, t2;
Object object=new Object();
t1 =new Thread(new OddPrinter(object),"firstThread");
t1.start();
t2 =new Thread(new OddPrinter(object),"secondThread");
t2.start();
}
}
This is definitely not the way synchronization should be implemented. In your implementation there is no monitor/locks or notify implementation since the lock acquired is soon out of scope of main thread's control.
It's completely wrong to do this way. In case you wanted to do something exclusive, the lock should be locked inside your thread -- not outside!.
public class MyThread implements Runnable {
private Object mutex;
public MyThread(Object sharedObject) {
this.mutex = sharedObject;
}
public void run() {
// Method 1 -- Class reference used as the mutex: locks and executes only one instance between the blocks
synchronized (MyThread.class) {
}
// Method 2 -- All the same instance of the object reference used as mutex receives a blocked interference, and only one thread is executed.
synchronized (mutex) {
}
}
// Method 3 - Only one synchronized method inside the class is executed at any given point in time.
private synchronized void produce() {
}
// Method 3 (Contd.) - Added in conjunction with produce() call
private synchronized void consume() {
}
}

Cannot .stop() .wait() or stop the thread in any way

I am having troubles with stopping a thread which is started from outside the class using a actionPerformed on a JButton. Code of the thread class below.
public synchronized void run ()
{
try
{
do
{
int minuta = vrijeme / 60;
int sekundi = vrijeme % 60;
System.out.println(minuta+" "+sekundi);
vrijeme = vrijeme - 1;
delay = delay - 1000;
if (minuta == stani && sekundi == 0)
{
}
try
{
Thread.sleep(1000);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
while (delay != 0);
{
//
}
}
catch (Exception e)
{
System.out.println("Stao" + e);
}
}
void pokreniThread()
{
(new Thread(new OdredenoVrijeme())).start();
}
synchronized public void zaustaviThread()
{
try
{
(new Thread(new OdredenoVrijeme())).wait();
}
catch (Exception e)
{
System.out.println("stao" +e);
}
}
}
Every time i call .sleep() .wait() or anything similar i get the following catch message:
java.lang.IllegalMonitorStateException
Under Java, you cannot have a sleep in the main process. Create a sub-thread, which will do the sleep, then post a message to a handler in the main-thread, to do something after the timeout.
If you want to stop a thread itself, set a variable inside the thread like is_stopping=true, then inside the thread you could set a variable is_running=false after the thread stops itself.
is_running=true;
while (is_running & !is_stopping)
{
do_something();
sleep();
}
is_stopping=false;
is_running=false;
In java the main thread is playing a scheduler part in the program. So in a multithreading situation you have these parts:
scheduler/controller
provider
customer
The main thread should always play the scheduler/controller part of the program. BTW you are not using multithreading in a good way. use synchronized when its absolutely necessary.
look at the following code. you should use synchronization like this:
public class BlockingQueue<T> {
private Queue<T> queue = new LinkedList<T>();
private int capacity;
public BlockingQueue(int capacity) {
this.capacity = capacity;
}
public synchronized void put(T element) throws InterruptedException {
while(queue.size() == capacity) {
wait();
}
queue.add(element);
notify(); // notifyAll() for multiple producer/consumer threads
}
public synchronized T take() throws InterruptedException {
while(queue.isEmpty()) {
wait();
}
T item = queue.remove();
notify(); // notifyAll() for multiple producer/consumer threads
return item;
}
You cannot stop a thread from an external context. The thread should stop itself when some condition changes.
You have to hold a flag in your thread that you want to stop, and the thread to check the flag in a loop. If the flag is changed, then the thread itself should do nothing and it will exit by itself

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 run a thread after another?

Create three threads and the main thread. Execute each thread as simultaneous tasks. Display information when exiting each thread.
I can run two threads with above exercise, but it hard to three threads. This is my program.
package Thread;
import java.util.concurrent.atomic.AtomicBoolean;
public class Test {
static AtomicBoolean lock = new AtomicBoolean(false);
public static void main(String[] args) {
Thread t1 = new Thread(new Runnable() {
#Override
public void run() {
System.out.println("New Thread: "
+ Thread.currentThread().toString());
for (int i = 5; i > 0; i--) {
synchronized (lock) {
if (lock.get()) {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("First: " + i);
if (i == 1) {
System.out.println("Second exiting.");
}
lock.set(true);
lock.notify();
}
}
}
});
Thread t2 = new Thread(new Runnable() {
#Override
public void run() {
System.out.println("New Thread: "
+ Thread.currentThread().toString());
for (int i = 5; i > 0; i--) {
synchronized (lock) {
if (!lock.get()) {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("Second: " + i);
if (i == 1) {
System.out.println("Second exiting.");
}
lock.set(false);
lock.notify();
}
}
}
});
t1.start();
t2.start();
try {
t1.join();
t2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Main thread exiting.");
}
}
And the result:
Can you give me some methods or tips to resolve this problem. Thank you for your reply!
It's unclear what you want three threads to do. With two threads you have
one waiting on the bool to be false and one waiting on it to be true, right?
With three threads you need three states to wait on. You also need to be
really careful to set it up in a way so the state transitions happens exactly
in the right order and a set amount of times.
Either try to write that program, and tell us what goes wrong, or if you want
design help it might be good to tell us more about what you want to achieve in
the end.
A suggestion if you have a real multithreaded problem that needs to be solved
is to look into something like queues. They are really nice high level abstractions
that makes working with threads much nicer.
More likely though, you have some artificial task that needs to be solved, and then
you need to speak a bit about the constraints you have.
Read tutorials here about Thread synchronization in Java.
public class sync extends Thread {
public void run() {
synchronized (this) {
for (int i = 5; i > 0; i--) {
System.out.print("Thread Name :" + Thread.currentThread().getName() + i+"\n");
}
}
}
}
class demo {
public static void main(String args[]) {
sync obj1 =new sync();
sync obj2 =new sync();
sync obj3 =new sync();
obj1.setName("First");
obj2.setName("Second");
obj3.setName("Third");
obj1.start();
obj2.start();
obj3.start();
}
}
O/p:
Thread Name :First5
Thread Name :First4
Thread Name :First3
Thread Name :First2
Thread Name :First1
Thread Name :Second5
Thread Name :Second4
Thread Name :Second3
Thread Name :Second2
Thread Name :Second1
Thread Name :Third5
Thread Name :Third4
Thread Name :Third3
Thread Name :Third2
Thread Name :Third1
HOPE THIS HELPS :)

Categories

Resources