Java Thread.suspend precise semantic - java

This question is NOT about alternatives to Thread.suspend.
This is about the possibility to implement a bias lock with Thread.suspend, which (I believe) can't be implemented with Thread.interrupt or similar alternatives.
I know Thread.suspend is deprecated.
But I want to know the precise semantics of Thread.suspend.
If I call thread1.suspend(), am I guaranteed to be blocked until thread1 is fully stopped? If I call thread1.resume(), can this call be visible to other threads out of order?
More over, if I successfully suspend a thread, will this thread be suspended at a somewhat safe point? Will I see its intermediate state (because Java forbids out of thin air value even in not properly synchronized program, I don't believe this is allowed) or see something out of order (if suspend is an asynchronous request, then sure I will see that kind of thing)?
I want to know these because I want to implement some toy asymmetric lock within Java (like BiasedLock in HotSpot). Using Thread.suspend you can implement a Dekker like lock without store load barrier (and shift the burden to the rare path). My experimentation shows it works, but since a Thread.sleep is enough to wait for a remote context switch, I am not sure this is guaranteed behavior.
By the way, are there any other way to force (or detect) remote barrier? For example, I search the web and find others use FlushProcessWriteBuffers or change affinity to bind a thread to each core. Can these tricks done within Java?
EDIT
I came up with an idea. Maybe I can use GC and finalizer to implement the biased lock, at least if only two threads are there. Unfortunately the slow path may require explicit gc() call, which isn't really practical.
If GC is not precise, I maybe end up with a deadlock. If the GC is too smart and collect my object before I nullify the reference (maybe the compiler is allowed to reuse stack variables, but is the compiler allowed to do these kind of things for heap variables, ignoring acquire fence and load fence? ), I end up with corrupted data.
EDIT
It seems a so called "reachability fence" is needed to prevent the optimizer moveing an object's last reference upward. Unfortunately it's no where.

Its semantics consist entirely of what is specified in the Javadoc:
Suspends this thread.
First, the checkAccess method of this thread is called with no arguments. This may result in throwing a SecurityException (in the current thread).
If the thread is alive, it is suspended and makes no further progress unless and until it is resumed.
But as you're not going to use it, because it's deprecated, this is all irrelevant.

Related

Is `Thread.checkAccess()` the appropriate replacement for `Thread.suspend()`?

IntelliJ suggests that I replace the deprecated Thread.suspend() with Thread.checkAccess(). Based on the (very brief) documents, checkAccess() seems like a good idea, but also seems quite different than .suspend(), which certainly seems very bad based on the docs. Yet those same docs don't seem to offer a useful alternative to .suspend(), except to suggest that each solution presented has some non-trivial drawbacks.
At the same time, while much better, it seems .checkAccess() relies on there being a SecurityManager implemented, so simply clicking "fix this" also seems like a bad idea without some well-thought-out implementation.
I have made the suggested change, and nothing has broken – yet... But I wonder...
If .checkAccess() is the best alternative, what is the best way to implement it in a nutshell? If it isn't, what is a better alternative?
According to the docs of Thread.suspend:
First, the checkAccess method of this thread is called with no arguments. This may result in throwing a SecurityException (in the current thread).
If the thread is alive, it is suspended and makes no further progress unless and until it is resumed.
So, invoking checkAccess() is preserving the "safe" part of the suspend() call, in that it will throw an exception if you don't have access, but it won't then proceed to the dangerous deadlocking operation.
I don't precisely know what "suspend" does - I have never used this method, and it is helpfully defined as "Suspends this thread". But if you simply want to wait for something to happen, you could wait on some object:
synchronized (thing) {
thing.wait();
}
then call thing.notify() from the thread you would otherwise be using to resume the thread.
But note that the primitive synchronization methods on Object are inherently difficult to use - for example, Object.wait() may spuriously wake up. You should rarely be using them directly (or Thread, for that matter).
There is a bunch of higher-level synchronization objects in the java.util.concurrent package. For example, you could have a queue shared between your "suspended" and "resuming" threads, where, at the point you want to suspend, one thread waits for the other to put something into the queue.

Why does Java ThreadPoolExecutor override finalize()

I'd like to know why the ThreadPoolExecutor finalize() method invokes its shutdown() method when it is known that the finalize method only gets invoked by the GC AFTER all of its threads have been stopped. So why does ThreadPoolExecutor override finalize() at all?
It seems misleading to me (and a source of a thread-leak my project) that ThreadPoolExecutor.finalize() invokes shutdown() as this gives the strong (but false) impression that
- ThreadPoolExecutor manages the lifecycle of its threads and will stop the threads when the GC collects the ThreadPoolExecutor object
- it is only necessary to invoke shutdown() or shutdownNow() if you want deterministic results as opposed to relying on the GC to tidy up (obviously, poor practice to do this!)
Notes
In this thread, why-doesnt-this-thread-pool-get-garbage-collected Affe explains why it is still necessary for the client to invoke shutdown()
In this thread, why-threadpoolexecutor-finalize-invokes-shutdown-and-not-shutdownnow the originator is puzzled by this topic but the answers aren't as comprehensive as in 1
The JavaDocs for ThreadPoolEecutor.finalize() do include the words "and it has no threads" but this is easily overlooked.
First, if you think this is a bug, then report it to Oracle.
Second, we cannot definitely answer your question, because you are essentially asking "why did they design it this way" ... and we weren't there when they made the decision.
But I suspect the reason is that the current choice was deemed to be the lesser of two evils:
On the one hand, if you a threadpool could be shutdown merely because it was no longer directly referenced, then threads that are doing real work could be terminated prematurely.
On the other hand, as you observed a threadpool that doesn't get automatically shutdown on becoming on longer directly reachable could be a memory leak.
Given that there are clearly ways to avoid the storage leak, I think that the 2nd alternative (i.e. the current behaviour) is the lesser of the evils.
Anyway, there is a clear evidence that this behaviour was considered by the designers; i.e. this quotation from the ThreadPoolExecutor javadoc:
Finalization
A pool that is no longer referenced in a program AND has no remaining threads will be shutdown automatically. If you would like to ensure that unreferenced pools are reclaimed even if users forget to call shutdown(), then you must arrange that unused threads eventually die, by setting appropriate keep-alive times, using a lower bound of zero core threads and/or setting allowCoreThreadTimeOut(boolean).
(And that sort of answer's #fge's comment. It happens when inactive worker threads are configured to time out.)
I also think there is an implementation-based reason as well. Take a look at the code here.
Each thread in the thread pool has a reference to a Runnable, which is actually an instance of the inner class ThreadPoolExecutor.Worker. This means that there is a strong reference path from the (live, though probably idle) Thread to the ThreadPoolExecutor.Worker object, and from that object to the enclosing ThreadPoolExecutor instance. And since live threads are always reachable, a ThreadPoolExecutor instance is remains reachable until all of its threads actually terminate.
Now I/we can't tell you which came first, the behaviour or the javadoc specification. See my "Secondly ..." point above ...
But, like I said above ("Firstly ..."), if you think this is a bug, report it to Oracle. And the same goes if you think that the javadoc is misleading ... though I think your argument there is weak given the material that I quoted.
As to why they overloaded finalize() to call shutdown() if shutdown() does nothing in this circumstance:
it may have done something significant in earlier versions, and
the shutdown() method ends by calling a hook method that is apparently overridden in subclasses to do something significant ... according to the comments.

How Java thread.stop() work?

I am actually looking for an easier way to kill the thread not matter where the thread is running at. But most of the solutions in internet point me to use boolean flag to control the execution of the thread, if I want to stop the thread then set the boolean variable to false.
But what if the task that in the runnable is a LONG linear task, which mean the task is not repeating? In that case, it is not so easy to create a 'while' loop to cover the whole block of task.
It is really so temptative to use Thread.stop but the warning "Deprecated" seem like quite dangerous to use. I have read through this article
Why Are Thread.stop, Thread.suspend, Thread.resume and Runtime.runFinalizersOnExit Deprecated?
but I can't understand
If any of the objects previously protected by these monitors were in
an inconsistent state, other threads may now view these objects in an
inconsistent state. Such objects are said to be damaged.
What does the "inconsistent state" mean? I appreciate if anyone can explain about this.
I want to extend my question to a more lower level of view, let say i = i + 1; in JVM (perhaps assembly language alike), maybe this Java statement will be split into few smaller instructions, for example like move i ; add i ; get i into memory 0x0101 (This is an example! I totally don't know assembly language!)
Now, if we call thread.stop, where actually will it stop at? Will the thread stop after a COMPLETED Java statement, or could be in the middle of the "assemble language"? If the answer is the second, could it be reason that we said
Such objects are said to be damaged.
?
Ok, my question is kind of confused, hope someone can understand and explain. Thanks in advance.
"Damaged object" is a high-level concept, it doesn't happen at the JVM level. A programmer designs his class with thread safety in mind by guarding critical sections with locks. It is an invariant of his class that each critical section either runs in full, or doesn't run at all. When you stop a thread, a critical section may have been interrupted in the middle, so disrupting the invariant. At that moment the object is damaged.
Stopping a thread conceals many more dangers, like no cleanup performed, no acquired resources released, etc. If a thread doesn't give up what it is doing, there is no way to make it stop without compromising the entire application.
In practice, whenever one faces the need to run alien code that may need to be forcefully aborted, this must be done in a separate process because killing a process at least performs OS-level cleanup and does a much better job of containing the damage.
The "inconsistent state" means state of data as your application cares about, state that your application logic have carefully produced by making your application thread-safe with locks/monitors etc.
Imagine you have this simple method:
public synchronized void doSomething()
{
count++;
average = count/total;
}
This method, along with other methods are synchronized, as multiple threads are using this object.
Perhaps there's a
public synchronized AverageAndCount getMeasurement()
{
return new AverageAndCount(average, count);
}
This assures that a thread can't read an incomplete measurement, i.e. if the current measurement is in the process of being calculated inside e.g. doSomething(), getMeasurement() will block/wait until that's finished.
Now, imagine the doSomething is run in a thread, and you call .stop() on that thread.
So the thread might be stopped right after it performs count++;, the monitor that's held is unlocked and the method terminates and average = count/total; is not executed,
That means the data is now inconsistent. Anyone calling getMeasurement() afterwards will now get inconsistent data.
Note also that at this point it is not very relevant whether this happens at a java statement level, or at a lower level, the data can be in an inconsistent state that you can't reason about in any case.
I'm no expert but this is what I think.
If you use Thread.stop() you cause the ThreadDeath exception that will cause all monitors to be released.
Since you provoke an exception you are applying an unnatural behaviour to the state of things.
Other threads relying on those monitors could enter in an inconsistent situation because they were not expecting it. And I don't think you can even anticipate the monitors releasing order.
I believe the concern is that the thread may be in the middle of a synchronize block performing multi-step updates to an object's members. If the thread is stopped abruptly, then some updates will have occurred but not others and now the object's state may render it unusable.
I have my doubts that the ThreadDeath handling will release a Lock backed by the AbstractQueuedSynchronizer which could leave the application on the path to a sort of deadlock.
At any logical point in your long sequence of code you can simply add:
if (Thread.interrupted()) {
throw new InterruptedException();
}
...this will exit execution at this point if it is determined that Thread.interupt() was called on the Thread executing the long running task.
It's not clear way to stop the thread.actually deprecated the stop() method whenever run() method is completed or any exception is occurred then thread is stop.by using the boolean flag variable .Bydefault "false"

Is there a fail-fast way of synchronization in Java?

Let's say I have a code snippet like this
synchronized(obj) {
do something;
}
If obj was already locked by some other thread, this code will wait until obj released and after that it will try to get the lock.
But I want to know if there is any way to jump over the code block if the lock can not be gained immediately?
Or put it another way, is there a way to detect whether or not an object is already locked ?
UPDATE:
Thanks for mentioning the Lock interface, but that require programs to obey the same contract, i.e, they all refer to a Lock object instead of the synchronized keyword.
I wonder if there is a built-in way of checking the locking status ?
Thanks.
Is there a fail-fast way of synchronization in Java?
I think it is a poor choice of terminology to use "fail-fast" to describe what you are trying to do here. Fail-fast implies that not being to acquire a lock instantly is a failure or application error; c.f. fail-fast iterators which throw an unchecked CCME. That's not the semantic model offered by locks in general, or here in particular. A better term would be "non-blocking"
Also, it is not clear that silently skipping a block of code because you can't acquire a lock is useful behavior. In most cases, the application needs to know that the "skip" path has been taken.
These points aside, you can't do it using primitive object locks.
(OK, on some JVMs you might be able to use sun.misc.Unsafe to do this, but that's a really bad idea. You are likely to find that your compiler, class loader or security sandbox stops you from using the Unsafe API ... as it should. Besides, this API is not called "unsafe" for nothing!)
The java.util.concurrent.locks.Lock API has a method that allows you to attempt to gain a lock without blocking. Specifically, the tryLock() method attempts to acquire the lock and immediately returns false if the lock is in use.
There are other higher level concurrency classes that you could use as ersatz locks; e.g. Semaphore.
Or put it another way, is there a way to detect whether or not an object is already locked ?
Actually, that is a bit different ... and not entirely useful either. Sure, you could (hypothetically) test if a lock is being held. (Indeed some Lock classes explicitly support this.) But that doesn't mean that you'd be guaranteed to be able to acquire the lock without blocking. If you make that (incorrect) assumption, you've introduced a Heisenbug into your code.
I wonder if there is a built-in way of checking the locking status ?
[Assuming that you are referring to primitive locks ... ]
No there isn't. At least, not within the running application itself. (A debug agent can do this, but it is not practical for an application to talk to its JVM's debug agent.)
If you want / need to do this kind of thing, you've got no real options that don't involve changing your application's locking mechanism. That's the way it is.
you can do it using java.util.concurrent.Semaphore it will allow you more control

How to remove deadlock in Java code using NetBeans

I have old code in Java which deadlocks... I never used netbeans as a development tool... however, I need to fix the code.
I ran the application in debug mode, clicked on check for deadlock and netBeans brought a screen. Two out of four threads were in red... see the screen dump below.
I'm new to multithreading, and on the top of that code is not mine...
What's most likely causing the problem?
As far as I can tell the problem is very likely related to the way in which (or more specifically the order in which) the multiple threads acquire and release locks.
In the above example the two threads need access to two locks (or monitors):
nano.toolbox.strategies.ESMarketMaker
nano.toolbox.strategies.ExecutionManager
From the stack trace on the two threads currently in a deadlock, we can see that thread 'ExecutionManager' has aquired the ExecutionManager monitor but is awaiting acquisition (while still holding the 'ExecutionManager' monitor) of the 'ESMarketMaker' monitor.
The 'StrategyManager' thread on the other hand, has acquired the 'ESMarketMaker' monitor but is awaiting acqusition (while still holding the 'ESMarketMaker' monitor) of the 'ExecutionManager' monitor.
This is a class example of deadlocks and the many ways in which order of acquisition of locks can cause deadlocks.
There are many ways to address these kind of problems:
If possible, all threads needing some set of locks to operate, must acquire the shared locks in the same order (the inversed order is the problem in the above deadlock). But this is not always possible, as multiple threads may have only semi-overlapping lock usage in different conditions, why it may be hard or impossible to design a protocol of acquisition that will ensure uniform ordering.
You may also use tryLock() instead, which is a non-blocking acquisition, it returns a flag to indicate success or failure and gives you the option to do something else before re-trying. One thing I would recommend in this case, is that if acquisition fails, it is to drop all currently owned locks and try from scratch again (thus giving way for any who is blocked on any or all locks the current thread holds, to complete their work, maybe freeing the locks this thread needs when it retries).
One thing to note though, is that sometimes when deciding on the protocol to use, you need more explicit control over your locks, rather than normal synchronization in Java. In these cases, the usage of explicit ReentrantLock instances can be a benefit, as these allows you to do stuff like inspecting whether a lock is unlocked or currently locked, and do non-blocking try-locks as described above.
I hope this helps, I'm sorry I can't be more specific, but I would need to see the source code for that. :-)
(Oh an p.s., a third thing one might opt for, if deadlock is something that must be avoided by all cost, is to look into modeling tools, to model a state machine over the states of the program and locks, which can be used together with analysis tools which can check for possible deadlocks in such a model and give you examples if any such is found).

Categories