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

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.

Related

Why does Thread class has static methods when we have currentThread() method?

Thread class has many static methods that are called by class name. Some of them are:
But yet, we are provided with method currentThread() that returns currently executing thread object. Some are:
Unfortunately, this created confusion in my head. When I think of a method I want, I have no clue whether I would found it as static or instance. So why did they make such two approaches?
I mean, couldn't they all be grouped in same 'calling'? For example why is sleep() static and not instance method called with Thread.currentThread().sleep()? Another weird example is between interrupted() and isInterrupted() defined in different manner. They do exactly the same thing, just interrupted() additionally clears interrupted flag. Has anyone logic answer to this, so I have no struggle where to find each method?
It's tricky; the answer is different for each method. Let's go through the ones you named:
Thread.sleep
Imagine I called: someOtherThread.sleep(1000L);. What would this mean? Surely that ought to mean: Sleep that other thread, not my thread. Except that's not something java offers: You can sleep your own thread, but you cannot arbitrarily tell some other thread to freeze like they're doing a mime act, mid execution of some arbitrary command. For example, if that thread is currently blocked on, say, waiting for the OS to deliver some bytes from a file read, that definitely cannot just fall asleep, and there are many, many other scenarios where a thread cannot do that.
Thus, java does not offer this functionality - you can't sleep other threads. Only your own. There are two different ways to make this at least somewhat clear in API design:
The first is to have sleep be an instance method (thus, you'd have to write e.g. Thread.currentThread().sleep(1000L);), and spec the method that it will guaranteed, always, immediately throw an IllegalStateException if you invoke it on any thread except your own. This means a compile/write-time detectable error condition would only be caught at runtime (this is bad; catching a problem earlier is obviously better than catching it later), it makes the code you'd have to write to sleep needlessly longer, and the existence of a sleep method you can invoke on thread instances sure suggests that you can sleep other threads. It'd just be crappy API design.
The second is to make sleep static.
Think of it this way: java.lang.Thread is a container for two mostly unrelated batches of methods: One is a set of methods you can use on threads (those'd be the instance methods). The other is a bunch of thread and flow related primitives, such as 'sleep', 'yield', and interrupt interaction. They just happen to be shoved into the same class.
interrupt
This is probably the trickiest. Unlike sleeping, you can in fact ask another thread's interrupt flag status.
The reason there are two methods are because of the more or less intended API design of the interrupt system.
The interrupt system is designed as follows:
If you want some thread to stop what it is doing for some unspecified reason (for example, you want it to re-check some condition, or just cease running, or anything else you can think of) then you need a mechanism to signal this. In particular, you'd want such a mechanism to ensure that any interruptable blocking operations, such as Thread.sleep(100000L) are interrupted. In other words, you can't just say: Whatever, it's up to the code itself, just, um, make an AtomicBoolean and check it a lot.
That's where the 'interrupt' system comes in. The idea is:
To interrupt any thread, raise its interrupt flag, with thatThread.interrupt();
All methods that do interruptable things should check this flag. The procedure is: If it is raised, then [A] clear it, and [B] handle the interruption, doing whatever the programmer intended to happen upon interruption (just stop running, or re-check some condition, re-read some config file, who knows - it's programming, whatever you want it to mean). If you CAN handle the notion of aborting some operation, but you CANNOT handle it, then instead clear that flag and throw InterruptedException, so that the caller can handle it.
As a result, any code that knows what 'I was interrupted!' means should BOTH check the flag (especially if that code has an event loop, which most thread-based code does have), AND catch InterruptedException from any method specced to throw it, and react in the exact same way to either catching that exception or having Thread.interrupted() return true.
Things go all sorts of wrong if you handle the fact that the interrupt flag is up, but you do NOT lower it. For example, if you abort your CPU-bound bitcoin mining or whatnot and just return back to your caller whilst leaving the flag up, then the next time caller invokes Thread.sleep, thread.sleep will notice the flag is up and IMMEDIATELY exit, not sleeping at all (exit by throwing InterruptedException, to be specific). That isn't intended. Hence why it is important that if you respond to an interrupt, you lower that flag.
So, let's go back to API design. There are two strategies:
Hypothetical design A
while (!Thread.currentThread().isInterrupted()) {
mineAnotherBitCoin();
}
Thread.currentThread().clearInterruptFlag();
Design B
while (!Thread.checkAndClearInterruptFlag()) {
mineAnotherBitCoin();
}
Note how design B is conceptually a lot shorter, does not have a 'gap' between checking the flag and clearing it, and therefore is fundamentally less error prone. Furthermore, for, well, reasons, it has been decided that raising an interrupt flag is something you can do to other threads (there is no point interrupting yourself, after all), but clearing one is a thing you can only do to your own thread.
B is what java actually has, except the method is somewhat strangely named interrupted(), and not checkAndClearInterruptFlag(). If you want an explanation of why some methods in java are somewhat suspectly named, it's because java does not like breaking backwards compatibility.
Fundamentally then, while they sound real similar, isInterrupted() and interrupted() do two very different things.
isInterrupted() is to check if some thread has already been interrupted and its response to this interruption is still pending (nothing has yet handled it).
interrupted() is something you put in the condition in your while loops that define the core body of your thread implementation (your 'event loop').
*) It doesn't help that the vast majority of examples of how to make threads in java are erroneous in that they don't properly do this. They tend to be while (true) or while (!running) {} or similar, either ignoring interruptions entirely or with a handrolled interrupt-esque 'running' concept.
So how do I know where to look?
Simple enough: If it's a thing that conceptually doesn't belong to any particular thread (such as 'how many threads are active right now'), or it is a utility concept (such as 'sleep'), or it is a thing that from a VM design principle can only be done to your own thread and not to anything else, then it is a static method in Thread.
If it's a thing that does belong to a particular thread AND the VM would let you do it to other threads (such as interrupting it, asking for its name, id, or priority, getting a stack dump, freezing this thread until the other thread completes, or setting its priority), then it's an instance method.
In many ways you can reverse this logic: If you want to do some thread related business, check the Thread class for something that seems to describe what you want. Then check if the method is static or not. If it is static, you don't get to do it to any other thread (such as clearing the interrupt flag, or sleep). If it's instance, you CAN do that to other threads (such as changing its priority level).
Because you can't make another thread sleep that is not the thread you are on. Even when you call Thread.currentThread().sleep(), you are calling the static method 'sleep'. If you were to call the sleep method on a different Thread object, it would still make the current thread sleep.
If you want to make a different thread sleep, you should set a flag that the other thread reads, which causes it to sleep.

Java Thread.suspend precise semantic

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.

Is Executors.newSingleThreadExecutor() the appropriate choice for running a task that I need to timeout?

We are unfortunately stuck for the medium term with having to call a method that can sometimes never return, and forever freeze the thread that called it. Fortunately that actual call interacts with little else in the system, and returns no value. So we're thinking that until we can fix the offending code, we need to run the invocation in a separate thread that we can monitor and interrupt if it exceeds a timeout.
Clearly smarter people than I have already solved this problem and left their gifts in the concurrent package, and since this will be my first use of anything in the concurrent package, I'd just like to confirm that I'm picking the best approach.
So I'm thinking I'd get an ExecutorService by calling Excutors.newSingleThreadExecutor, submit a Runnable to it, and then call the overload of Future.get() that accepts a timeout as a parameter.
The actual task to perform is just to call a single void method on an object that I can pass into the constructor of the Runnable.
If this is the right approach, or close, I'd also really appreciate a short code sample if you're feeling generous with your time. :)
Thanks
Clearly smarter people than I have already solved this problem
Actually its not really solved IMHO.
To interrupt a task it has to be well behaved and check the interrupt or it won't actually stop. However, if its well behaved its unlikely to need to be killed in the first place.
You can use the deprecated Thread.stop() if you are sure there is no possible side effects. This requires using a plain Thread. Its not ideal even if you "know" this shouldn't cause a problem and again using a flag to stop the task is preferred.

Notifying a single thread: notify, notifyAll or concurrent.locks.Condition?

I need to wake up or send to sleep a single Thread sometimes, and I'm wondering what is the best and most efficient way to do it.
The first solution is signaling combined with wait-notify (I know how to implement this pattern properly, that's not the question).
I read it somewhere that using the java.concurrent library and CountDownLatch for signaling is more efficient. I checked concurrent.locks.Condition as well, but this topic states that it's merely a (programmer-wise) more safe and generalized construct, without a performance benefit compared to notify/notifyAll. Peter Lawrey recommends using the Concurrency library instead of notify-notifyAll in this comment, so now I'm confused what is the best practice to use.
A related question: which is better performance-wise, notify or notifyAll in my case (i.e. if I have one thread)? I know there are lot of similar threads about this, but none of them give a clear answer. In my case, functionally, it doesn't matter which I use, but I wonder which is faster, then.
IMO they don't make much difference "performance-wise" since they all suspend the thread calling the corresponding wait so most likely the underlying mechanisms are very similar. And why would performance matter so much anyway? Unless you have some extremely fast wait/signal pattern in which the signal comes immediately after the wait, making a context-switch too expensive and requiring perhaps a spinlock instead, there's no need to worry about performance.
You should implement what you think is the most convenient method programming-wise and then benchmark and see if you really need something more performant.
wait-notify is perfectly fine.
since there's only one thread on the waiting list, there's no difference, semantics or performance wise, between notify and notifyAll.

Java: LockSupport.parkNanos vs Thread.sleep(...)

In some cases, most of us write things like this:
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
; // do nothing
}
Whether right or wrong, acceptable only in some test harnesses, is not my point.
My point is that the same code could be written,more succinctly, as:
LockSupport.parkNanos(2000* 1000000);
is there any reason why I should favour one approach over the other.
Readability: Thread.sleep has a pretty intuitive meaning. How would you describe (to another developer) your use of LockSupport.parkNanos? If that description primarily consists of "I want the current thread to sleep" then surely Thread.sleep is more descriptive.
The conciseness comes from the lack of interrupt handling - so create a wrapper method to do this if you want, which propagates the exception as a RuntimeException. Heck, if you're creating a wrapper method, you can use either implementation, although another thread could of course unpark your "sleeping" thread in the same way as it could interrupt it...
The docs for the method parkNanos provides the conditions in which the method can return. One of those conditions is: the call spuriously (that is, for no reason) returns. So basically it's OK to use it if you don't mind spurious wake-ups and some other Thread "unparking" the waiting thread in consideration. And of course, the comment by Jon pretty much nails the reasoning for preferring one over another.
LockSupport has a much more limited application, and does not support Exception handling. If you have to only lock a single thread, it is OK.
From the API:
these methods are designed to be used as tools for creating
higher-level synchronization utilities, and are not in themselves
useful for most concurrency control applications.

Categories