Java: Two threads, interrupting eachother - java

I want to write a code with two different threads. The first one does somethin, the second one waits a specific time. The thread that ends first should interrupt the other one.
My problem is now, that the thread, I initialized first, cannot access/interrupt the second one, it always gives out the "symbol not found"-error. If I swap the positions of the threads in the code, it is the same, only the other way around.
Is there a possibility, to make both threads "global" and accessable by the other one? Please give coding examples, where to put the public void main, the void run(), etc., if possible, so I just need to add the code itself.
Thanks
Code examples:
public class FTPUpload extends Thread {
public static void main (String args[]) {
_//some code_
final Thread thread1 = new Thread(){;
public void run() {
_//code of thread1_
}
final Thread thread2 = new Thread(){;
public void run() {
_//code of thread2_
}
thread1.start();
thread2.start();
}
}

For your question is (currently?) a bit vague, my answer may not be that helpful. But...
Try declaring the Thread objects first and use them later. So each might be know to the other.

You can create a bool static Variable which both can access and once one of them is finished sets it to true, and you have to check this variable during the job in each thread, either on different places or if you have a loop in the loop for example.
Alternatively you can write a dummy file somewhere by the thread finished 1st and keep checking if file exists in both threads. The main idea is having a shared resource both can access.
Read this Question it very informative: Are static variables shared between threads?
My Idea May not work up to some answers but the one with the file should actually work.

A typical solution for communicating between 2 threads is to use condition variables. Thread1 could block on the condition variable, then when Thread2 has done what it needs to do and wants to tell Thread1 to go, it signals Thread1 via the condition variable, thus releasing its block. Both threads must be initialized with the same condition variable. Here is an example.
If you want both threads to wait until the other is initialized, this can be performed using a barrier sync (called a CyclicBarrier in Java). If Thread1 hits the barrier sync first it will block, until the other thread hits the barrier sync. Once both have hit the barrier sync, then they will continue processing. Here is an example.
Both condition variables and barrier syncs are thread safe, so you dont have to worry about if you need to synchronize them or not.

The general principal is to create a lock and condition outside both threads. The first thread acquires the lock and signals the condition when done. The second thread acquires the lock and awaits the condition (with timeout if needed). I am very concerned that you are relying on Thread.interrupt() which is a bad plan.
final Lock lock = new ReentrantLock();
final Condition done = lock.newCondition();
...
// in thread 1 when finished
lock.lock();
try {
done.signalAll();
} finally {
lock.unlock();
}
...
// in thread 2 for waiting
lock.lock();
try {
done.await(30,TimeUnit.SECONDS); // wait for the done or give up waiting after 30s
} finally {
lock.unlock();
}
Using the lock will ensure that both threads see a consistent view of shared objects, whereas Thread.interrupt() does not guarantee you have passed a boundary
A refinement is to use a CountDownLatch
final CountDownLatch latch = new CountDownLatch(1);
...
// in thread 1
latch.countDown();
...
// in thread 2
latch.await(30,TimeUnit.SECONDS)
This abstracts away the lock.
Others have suggested effectively a spin lock scanning for a file on the file system. Such an approach could lead to thread starvation or if not slower performance than a lock or latch based solution... Though for inter-process as opposed to inter-thread within the one jvm, file based is ok
I recommend the book "Java Concurrency In Practice" if you think you know threading go to a bookshop, open the book and try to predict what the program on page 33 will do... After reading that page you will end up buying the book

Related

ReentrantLock Condition how does signallAll() work?

I am trying to understand How does signalAll() not break the critical section for example
//Some Class Here is Trying to use an resource which is to to initialized in an seperate thread
ReentrantLock lock=new ReentrantLock();
Condition wait=lock.newCondition();
Resource res=new Resource(lock); //An Important Resource Which Should Be Accessed Only By One Thread At A Time
void doStuff()
{
lock.lock();
try
{
if(!res.initialized.get()) //Check If Resource Was Previously Not Initialized
{
res.init();//Spawns An Seperate Thread For Initialization
wait.await();//If Resource Is Not Initialized Make Whatever Thread Which Reached This Point Wait
}
res.use(); //Here Is What I Don't Understand If Let's Say 5 threads were parked in the previous statement then when signalAll() is called won't all 5 threads wake up simultaneously and resume execution at this point and use this resource at the same time and break this resource? But it dosen't turn out like that why?
}
}
finally{lock.unlock();}
}
private static final class Resource extends Thread
{
private final ReentrantLock lock;
private final Condition init;
private final AtomicBoolean
started=new AtomicBoolean(false),
initialized=new AtomicBoolean(false);
private Resource(ReentrantLock lock)
{
this.lock=lock;
this.init=lock.newCondition();
}
private void init()
{
if(!initialized.get())
{
if(!started.get())
{
start();
started.set(true);
}
while(!initialized.get()){init.awaitUninterruptibly();}//In case of spurrous wakeups check repeatedlly
}
}
private void use(){}//Important Stuff
private int get(){return 5;}
#Override
public void run()
{
lock.lock();
try
{
TimeUnit.SECONDS.sleep(5);
initialized.set(true);
init.signalAll(); //This should in the above example wake up all 5 threads simultaneously and break the critical section but that does not happen how?
}
catch(InterruptedException ex){}
finally{lock.unlock();}
}
}
With just signal() only one thread wakes up and resumes execution at the critical section so nothing breaks but with signalAll() multiple threads resumes execution at the point it was parked[i.e inside the critical section] so how does nothing break? and when/where should we use each i.e best practises
The short answer:
await() does not only suspend the current thread, it also releases the lock. signalAll() wakes up all suspended threads but each thread has to re-acquire the lock before the await() call can return. With it, even after calling notifyAll() the critical section can only be entered by a thread after the thread that acquired the lock before relinquishes the lock.
The long answer:
For better understanding - let's pretend that neither await(), singal() nor signalAll() would exist in Java. How would you wait for the asynchronous initialization of your resource? Your code would probably look something like this:
void doStuff(Resource resource) throws InterruptedException {
lock.lock();
try {
while (!resource.isInitialized()) {
resource.startAsyncInit();
lock.unlock();
Thread.sleep(100);
lock.lock();
}
doSomethingWith(resource);
} finally {
lock.unlock();
}
}
But this would have the following drawback:
Each thread that waits for initialization is suspended and woken up again and again.
Each single thread acquires the lock and releases the lock again and again.
The more frequent you do this and the more threads are waiting the more expensive
does it get. This busy waiting consumes CPU. Without an explicit sleep the code would easily
lead to 100% CPU usage.
await() allows you to replace the busy waiting with a signal-based mechanism.
All waiting threads are suspended and do not consume any CPU while they are waiting.
Only sporadically occuring spurious wake-ups (at least on some systems) may consume some CPU.
When to use singal(), signallAll() in general:
Waking up a thread and suspending a thread is not for free and gets more expensive with
the number of threads. If you have a resource that has to be initialized
before it can be used concurrently by all threads it makes sense to wake up all threads at once by calling signalAll().
But think of a consumer/producer pattern with multiple consumer threads and multiple producer threads where a single producer thread provides only one work item that is processed by one consumer thread. In this case it would make much more sense that a producer thread wakes up only one consumer thread instead of all. Otherwise all awakened threads would first compete for the single work item, one would win and all others would have to be sent back to sleep again. This would have to be repeated every time when a single work item is produced. When a lot of work items are produced in short time
you would finally loose all the advantage of the singalling. The majority of threads would be suspended and woken up again and again, they would compete for one single item again and again and you would finally end up with nearly the same overhead as the example above with busy waiting but without an explicit sleep ;-)
signal() vs signalAll() in your example:
When the first thread gets the hold of the lock it calls the init() method, starts the thread for initialization and then releases the lock when it calls awaitUninterruptibly(). The initialization thread in the meanwhile tries to acquire the lock but it will not get it until awaitUninterruptibly() is called.
Locks are by default unfair. This means that it is not guaranteed that the longest-waiting thread will get the lock first. When awaitUninterruptibly() is actually called and the lock is released other theads may have already tried to acquire the lock in the meanwhile by calling the lock() method. Even when your initialization thread tried to acquire the lock first, it is not guaranteed that it will get the lock before any other thread. Every other thread that will get the lock before your initialization thread will be able to call the await() method. If you then only call singal() in your initialization thread all threads that were able to get to the await() call would never be woken up and sleep forever. To avoid this, it is essential to use singalAll() in your example. Another possibility would be to use a "fair" lock (see the JavaDoc of the ReentrantLock). With a "fair" lock it shouldn't make any difference whether you call singal() or signalAll(). But since "fair" locks have quite an overhead I would suggest to keep the unfair lock and use singalAll().
Whether you run into a situation where some threads sleep forever depends on the right timing. So you propably may run this code on one host hundreds of times without any problem but run into this situation frequently on other hosts. Even worse, in environments with spurious wake-ups you would run into this only from time to time ;-)

about synchronization with two threads [duplicate]

This question already has answers here:
Threads access on Synchronized Block/Code Java
(2 answers)
Closed 5 years ago.
Say one singleton instance accessed by two threads. Two threads are accessing the same function called doTask().
public class MySingleton {
Object lock = new Object();
// I omit the constructor here.
public void doTask() {
//first non-synchronized code
synchronize(lock) {
//some heavy task
}
//final non-synchronized code
}
}
If thread B is doing the heavy task, when thread A access doTask(), I know Thread A will run the //first non-synchronized code, then thread A noticed the lock is acquired by Thread B, so it can't run synchronized //some heavy task. But would thread A skip the synchronized heavy task continue run //final non-synchronized code or will thread A wait for the lock without even executing the //final non-synchronized code?
(I know I can try it out, but currently I don't have a proper development environment...)
The synchronized block in java forces threads to wait until they can acquire the object's lock.
It will wait until B is done, and then snag the lock for lock, and run the code inside the block, and continue out the other end.
It is important to note that when B finishes executing the contents of some heavy task it will release the lock on lock and run the final non-synchronized code at the "same time" that A runs the synchronized block.
When one thread acquires the monitor of synchronous object, then the remaining threads will also try to acquire it and this process is termed as POLLING. Because all the remaining threads try to acquire the monitor of that object by repeatedly checking the monitor lock status. The moment when the lock is released it can be acquired by any thread. It's actually decided by the scheduler.
Thread A will always wait indefinitely until Thread B releases the lock.
In the extreme case, if the lock is never released, Thread A will be stuck forever.
Sometimes this is good enough but often you will need better control over things, this is when classes like ReentrantLock come handy.
This can do everything synchronized offers, but can also do things like checking whether the lock is owned by the current thread already, attempting to acquire the lock without waiting (failing instantly if the lock is already taken by another thread), or limit its waiting to a certain amount of time.
Please also note that while these solutions can be used to control mutual exclusion, this isn't their only function, they also play an important role in visibility.

Java Thread Visibility and Synchronized

I have been experimenting Java thread visibility problem with the popular example of sending a stop signal to the thread by means of a shared boolean and non-volatile variable and the target thread does not seem to get it) as below:
public class ThreadVisibilityTest {
//Shared variable to send a signal to the thread
static boolean stopped = false;
public static void main(String[] args) throws Exception {
Thread targetThread = new Thread(new Runnable() {
public void run() {
while(!stopped) {}
System.out.println("Target thread gets signal and stops...");
}
});
targetThread.start();
TimeUnit.SECONDS.sleep(5);
stopped=true;
System.out.println("Main thread has sent stop signal to the thread...");
}
}
Main thread sends stop signal to the target thread after 5 seconds by means of setting stopped to true and the target thread can not get it and so does not stop.
Defining stopped variable as volatile obviously solves the problem.
Bu then I realized that if I make stopped variable non volatile but instead access it in a synchronized context in the target thread, target thread gets the final value and stops. So thread visibility problem seems to be solved just like using volatile.
Thread targetThread = new Thread(new Runnable() {
public void run() {
while(true) {
synchronized(this) {
if(stopped) break;
}
}
System.out.println("Target thread gets signal and stops...");
}
});
And also the object monitor to be used for synchronization seems to have no effect as follows:
synchronized(Thread.class) {
if(stopped) break;
}
Is this something that happens by chance or do I miss something?
Or can we say that accessing shared variable with mutual exclusion seems to force target thread to refresh its cache memory just like accessing a volatile variable?
If the latter is true which way do you suggest to overcome thread visibility issue, by means volatile keyword or access with mutual exclusion?
Thanks in advance
Is this something that happens by chance or do I miss something?
You missed the chapter in the Java Language Reference (JLS) that talks about the Java Memory Model. Either that, or you missed working through the concurrency chapter in the Java tutorial. https://docs.oracle.com/javase/tutorial/essential/concurrency/
Either way, you would have learned that if thread A exits from a synchronized block, and then thread B enters a block that is synchronized on the same object, then everything that thread A wrote before releasing the lock is guaranteed to be visible to thread B after thread B locks the lock.
I think mutual exclusion also provides memory visibility as stated in Java Concurrency In Practice (By Brian Goetz) in section 3.1.3 Locking and Visibility.
See, you are reading it in synchronized context but not writing in the synchronized context. That might cause problem.
As other answers have already pointed out, memory visibility is established when using synchronization.
However, it would be preferable to use a volatile shared variable (unless synchronization is needed for non visibility related issues) for greater concurrency. Overuse of synchronization forces threads to constantly wait for each other, when it would be safe and faster to work concurrently.
Synchronized blocks or methods work very similarly to volatile variables regarding visibility. After the thread exits the synchronized block, it releases the monitor, which has the effect of flushing CPU registers to CPU cache - so that writes made by that thread are visible to other threads.
Before entering the synchronized block, the thread acquires the monitor, which has the effect of invalidating the local processor cache (CPU registers) and forcing the thread re-read from the CPU cache. Therefore, all changes made by the previous release would be visible to the thread which has the same monitor lock.
In the above example, the write was made outside of synchronized context. In this scenario, according to JMM, there is no guarantee as to when the flush CPU register will occur and - consequently, whether the latest values would be available to other threads.
For this reason, you can assume that the code “works” probably because the flush occurs in time and the synchronized block forces the thread to re-read from CPU cache on each loop. Besides, the JMM states that the “happen-before” visibility guarantee requires the same monitor lock. So, anything beyond that is just by chance.
Source: https://www.cs.umd.edu/~pugh/java/memoryModel/jsr-133-faq.html#synchronization

Multithreading synchronization issues

I have code like this:
public class OtherClass {
// OtherClass
public synchronized static void firstMethod() {
System.out.println("FIRST METHOD");
}
public synchronized static void secondMethod() {
System.out.println("SECOND METHOD");
// In actual code I would have try catch for this but here I just didn't
// include it
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public class MainClass {
// main method of MainClass
public static void main(String args[]) {
Thread firstThread = new Thread() {
public void run() {
while (true) {
OtherClass.firstMethod();
}
}
};
Thread secondThread = new Thread() {
public void run() {
while (true) {
OtherClass.secondMethod();
}
}
};
secondThread.start();
firstThread.start();
}
}
The reason I start the 2nd thread first is because I want the secondMethod of OtherClass to execute first. I should see "FIRST METHOD" and "SECOND METHOD" in the console output every 5 seconds. The reason being is that since Thread.sleep does not relinquish the lock, for 5 seconds the first thread doesn't have access to the first method because the second thread has got a lock on the class while it's in the second method which tells the thread to sleep for 5 seconds. But I get very unexpected results. All I get in the console output is "SECOND METHOD" every 5 seconds. The firstMethod isn't called.
Ignoring compilation problems in your code.
That's just coincidence. The thread scheduler simply decides to continue executing the second thread which reacquires the lock too fast.
Run it long enough (or with a shorter sleep time for faster results) and you'll see the other method get invoked.
The reason I start the 2nd thread first is because I want the secondMethod of OtherClass to execute first.
That's not how threads work. That's not what threads are for. Threads provide no guarantees of what happens before what else except where you provide explicit synchronization between them; And generally speaking, the more synchronization you use, the less you will benefit from having multiple threads.
In your example, you have explicit synchronization that prevents any concurrent executions of firstMethod() and secondMethod(), but you have nothing that guarantees which one will run first, and which one will run second. Chances are, that main() will terminate before either of them runs. At that point, it's up to the scheduler to pick which one will run when. There is no requirement that it start them in the same order that your code called their start() methods.
Your example may be educational, but it also is an example of when not to use threads. Your synchronization is very heavy handed. Your program basically does two things, firstMethod() and secondMethod(), and the synchronization insures that they can not be overlapped. In production software, if you have two tasks that must not overlap, then it'll simplify your program's logic if they are always performed by the same thread.
All I get in the console output is "SECOND METHOD" every 5 seconds. The firstMethod isn't called.
Your question was edited before I got to see it, so I don't know whether you're talking about the original version, or the fixed version. But in any case:
The synchronization in your program does not guarantee that the two threads take turns. All it does is prevent them both from printing at the same time.
Each of your threads runs a loop that grabs the lock, prints something, releases the lock, and then immediately tries to grab the lock again. When a running thread releases a lock, and then immediately tries to get it again, the chances are it will succeed. It doesn't matter that some other thread was waiting for the lock. The OS doesn't know what your program is trying to accomplish, but it does know that it can make more efficient use of the CPU by letting a thread continue to run instead of blocking it and un-blocking some other thread.
You will need to use some additional synchronization to make the threads take turns, but like I said, in a real program, the more synchronization you use, the less benefit there is to using threads.
Your processor won't execute your Threads at the same time; it'll run your second thread every time bevore your first thread.
The behaviour is clear: Your processor executes your second thread. Then, the processor executes your first thread and sees that it is locked by your second thread. After 5 seconds, your second thread is called again. It makes the output, releases the lock and locks it again. If your first thread is called again, it is locked again.
To fix this, add Thread.yield() at the end of your while. This will make the processor call the first thread before continuing to execute your second thread (the first thread won't be the only one that is called, it just removes your second thread 1 time from it's execution). Then your first thread gets the lock, waits 5 seconds, outputs and calls Thread.yield(); then your second thread gets the lock again and so on.
What you are experiencing is thread starvation. In your case, one thread is being blocked indefinitely waiting to enter a synchronization block because the other thread is constantly allowed access.
To overcome thread starvation you need to employ some sort of fairness locking. Locks that are conceived as fair give priority to the threads waiting the longest to acquire said lock. Such a locking strategy eliminates the possibility of thread starvation and insures all waiting threads will be executed at some time.
Fairness locking in Java can easily be accomplished by using a ReentrantLock with a fairness parameter set to true.

Can we change the lock after thread enter synchronized block?

I am asking this question is just for curiosity, I know it is stupid to do such thing.
public void doSomething()
{
synchronized(object_A){
count++;
average = count/total;
}
}
Now let say I have 2 thread run concurrently (calling function doSomething()), while the first thread already enter the block, let say at the line "count++", the second thread is blocked and waiting the lock.
Now I try to do object_A = new LockObject() (in another thread). Now what happen to thread 1 and thread 2?
Will thread 2 enter the block? Since it already executed statement "synchronized(object_A)", is it too late to change the lock?
Will thread 1 change the lock while in the sync block (assume thread 1 still in the block)?
It's like ignis said, but Thread 2 will see the new reference after Thread 1 is done, because it has to refresh all variables.
The only problem would be data integrity. Threads will be synchronizing on different locks and the data protected by the locks will have wrong values. Locks are created in the instance initializer's as private final fields or in the constructor of the class.

Categories

Resources