Good thread design: "Method in Thread" or "Thread in Method" - java

This is just a general question on actual thread design. I'm using Java on android specifically but general design would be the better focus of this question.
Its simple enough, which is better method in thread or thread in method.
Example,
Lets say we have 3 methods/functions/whatever.
public void readMail()
{
//Logic...
}
public void postQuestion()
{
//Logic...
}
public void answerQuestion()
{
//Logic...
}
Is it better to have
A: Thread within Method
public void readMail()
{
new Thread(new Runnable()
{
public void run()
{
//Logic
}
}).start();
}
And then call your method as you normally would in any OO situation. Say
Email.readMail();
B: Method within Thread
//note this could be inside a method or a class that extends runnable
new Thread(new Runnable()
{
public void run()
{
readMail();
postQuestion();
answerQuestion();
}
}).start();

Method within Thread
[+] If your methods do not need to ensure the property of concurrent execution, or they have deterministic runtime behavior (time and performance), this approach can be a high-level management for concurrency of the application; i.e. concurrency remains at the level of objects rather than methods.
[-] Since the concurrency remains at the level of threads/objects, the application may lose the notion of responsiveness. A user may be "posting a question" while another is "fetch an answer"; and both can be dealt with concurrently.
Thread with Method
[+] More fine-grained concurrency control: each method becomes a unit of execution at the OS level. That's why as #LouisWasserman mentioned, maybe, taking advantage of Executor framework would make more sense.
[-] Generally threads are resourceful and expensive; so this means that you will have performance issues when used in high-frequency/load application with numerous calls to one method. Specially, if there are inter-method data/logic dependencies. In this regard, synchronization also becomes a concerns and that's why using Actor models can help more.
I'd suggest reading more about Actor models and their available implementations.

The second option is more amenable to being rewritten to use Executors and the like, so I'd prefer that version.

I prefer:
C: One Thread One Object
public class Test {
public static class MailReader implements Runnable {
public void readMail() {
//Logic...
}
#Override
public void run() {
while (!Thread.currentThread().isInterrupted()) {
readMail();
}
}
}
public static class QuestionPoster implements Runnable {
public void postQuestion() {
//Logic...
}
#Override
public void run() {
while (!Thread.currentThread().isInterrupted()) {
postQuestion();
}
}
}
public static class QuestionAnswerer implements Runnable {
public void answerQuestion() {
//Logic...
}
#Override
public void run() {
while (!Thread.currentThread().isInterrupted()) {
answerQuestion();
}
}
}
public static void main(String[] args) throws FileNotFoundException {
new Thread(new QuestionAnswerer()).start();
new Thread(new QuestionPoster()).start();
new Thread(new MailReader()).start();
}
}
This allows the full gamut of possibilities without any additional grok effort. If you want more mail answered than questions posted, make more MailReaders.
If you see
for ( int i = 0; i < 10; i++ ) {
new Thread(new MailReader()).start();
}
you know exactly what is intended and you know that will work.

At first design (A), every method is a SEPARATE THREAD in fact, while at second design (B), you have ONLY ONE THREAD.
It deeply depends on you application logic & the operation which every method performs:
If you need to run your methods parallel, then A is the correct answer, but if you need execute all methods sequentially in a thread, then B would be your choice.

If you are building a utility for other programmers to use, note that the client programmer may not care about threads at all and may just want to write a single-threaded program. Unless there is a very good reason to do so, you shouldn't force them to drag threading issues into a program which would otherwise work fine single-threaded. Does this mean your library can't use threads internally? No! But to a caller, your methods should appear single-threaded (except that they return faster than they would if they were implemented without threads).
How can you do this? When someone calls into one of your methods, block the calling thread, and pass the task off to a pool of worker threads, who can perform it in parallel. After the worker threads finish the task, unblock the calling thread and let it return a value to the caller.
This way you can get the performance benefits of parallelism, without forcing callers to deal with threading issues.
Now, on the other hand, even if you decide that your library doesn't need to use threads internally, you should still make it thread-safe, because client programmers may want to use threads.
In other words, there is no reason why the decisions of "thread in method?" and "method in thread?" need to be coupled. You can use "thread in method" if there are performance benefits to doing so, but that shouldn't affect the caller. (They should just be able to call the method and get the needed return value back, without worrying about whether you are using threads internally).
If your module is thread-safe, then it won't be affected either by whether the caller is using threads or not. So if the client programmer wants to use threads, they can also use "method in thread". In some situations, you may have both "method in thread" and "thread in method" -- your module may be using a worker thread pool + task queue internally, and you may have multiple caller threads pushing tasks onto the queue and waiting for results.
Now, while I am talking like you are building a library, in reality you are probably just building code for your own use. But regardless of that, the same principles apply. If you want to use threads for performance, it is better to encapsulate the use of threads behind an interface, and make it so the rest of the program doesn't have to know or care whether module XYZ is using threads or not. At the same time, it is best if you make each module thread-safe, so callers can decide whether to use threads or not.

Related

Is this ConcurrentLinkedQueue/wait/notify algorithm correct?

I know that typically for producer/consumer pairs like this, a blocking queue should be used. What I want here is only to understand better memory consistency in Java, interaction between concurrent data structures and locks, and also what is exactly the imprecision when determining the size of ConcurrentLinkedQueue.
The question is, does the algorithm below assure, that anything produced is consumed, as it would in the case of a plain non-thread safe queue? Note: I ran it several times and it always was the case.
import java.util.concurrent.ConcurrentLinkedQueue;
public class Produce extends Thread {
#Override
public void run() {
synchronized(Main.queue) {
Main.queue.add(1);
Main.queue.notifyAll();
}
}
}
public class Consume extends Thread {
#Override
public void run() {
synchronized(Main.queue) {
while(true) {
while(!Main.queue.isEmpty()) {
Main.queue.poll();
System.out.println("consumed");
}
System.out.println("empty");
try {
Main.queue.wait();
} catch(InterruptedException e) {
}
}
}
}
}
public class Main {
public static final ConcurrentLinkedQueue<Integer> queue =
new ConcurrentLinkedQueue();
public static void main(String[] args) {
(new Consume()).start();
(new Produce()).start();
}
}
The answer to your question is yes. The consumer will see all of the updates.
However:
This is not a sensible implementation. It looks like you are using the polling approach with wait / notify so that you don't need a busy loop to wait for the queue to become nonempty. But a better (simpler, more efficient) approach would be to use a BlockingQueue instead and use the blocking get() method.
For what it is worth, you are negating any possible scalability advantages of using ConcurrentLinkedQueue by using the queue object as a mutex to do wait / notify signalling. (This would also apply if you used a different object as the mutex. The problem is the mutual exclusion!)
If you are going to do it this way (for whatever reason), a notify() would be preferable to a notifyAll(). Only one consumer is going to be able to consume that (single) element you added to the queue. Waking up all of the consumers is unnecessary.
It is not a good idea to extend Thread. A better way is to put your business logic into a Runnable (or a lambda) which you pass as a Thread constructor parameter. Read: "implements Runnable" vs "extends Thread" in Java
You also were interested in:
... what is exactly the imprecision when determining the size of ConcurrentLinkedQueue.
The answer to that is in the javadoc for ConcurrentLinkedQueue:
"Beware that, unlike in most collections, this method is NOT a constant-time operation. Because of the asynchronous nature of these queues, determining the current number of elements requires an O(n) traversal."
"Additionally, if elements are added or removed during execution of this method, the returned result may be inaccurate. Thus, this method is typically not very useful in concurrent applications."
In other words, ConcurrentLinkedQueue counts the queue elements, and does not give an accurate answer if elements are being added and removed at the same time.

Killing a thread or an asynchronous task

let's say I use a jar that IBM has created.
Let's say that this Jar has a function that I need but is ultimately build as such:
while (true) {
System.out.println(1)
}
(of course it doesn't really just printing 1, but for the example let's say it is)
So, I made the call to the function that does it in another thread using future. How can I completely kill the thread that this code is running in? Or alternatively, how can I kill the asynchronous task in Kotlin that runs the code.
Solutions in Kotlin or Java will be great,
thanks in advance!
EDIT:
I've found out, that if this is a thread, I can Thread#stop() it to really make it stop. But unfortunately making the constructor throwing exceptions multiple times, causes the JVM to erase the class from memory causing a NoClassDefFoundError when instantiating the class the next time..
If you can capture it's thread you should be able to kill it so long as it is doing some kind of blocking function internally.
class OtherFunction implements Runnable {
#Override
public void run() {
while(true) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// We assume the thread will exit when interrupted.
System.out.println("Bye!!");
return;
}
System.out.println("Hello");
}
}
}
class Killable implements Runnable {
final Runnable target;
private Thread itsThread;
Killable(Runnable target) {
this.target = target;
}
#Override
public void run() {
// Catch the thread id of the target.
itsThread = Thread.currentThread();
// Launch it.
target.run();
}
public void kill() {
// Give it a good kick.
itsThread.interrupt();
}
}
public void test() throws InterruptedException {
OtherFunction theFunction = new OtherFunction();
Killable killableVersion = new Killable(theFunction);
new Thread(killableVersion).start();
// Wait for a few seconds.
Thread.sleep(10000);
// Kill it.
killableVersion.kill();
}
It seems like Thread#stop() solved my problem. I know it's deprecated and can be prevented with catch(Throwable t) but at least it did the trick for me.
By the way, to get the thread from the executor, I've used AtomicReference<Thread> and set it in the callback.
Thread#stop() is deprecated as 'inherently unsafe' and should be avoided if at all possible.
It's a source of instability and corruption and may fail anyway!
It actually causes a ThreadDeath exception to be throw in the target thread.
The authors of whatever code it pops into are unlikely to have expected that outcome.
Objects may be in an inconsistent state, external resources may be held and get leaked, files may be incompletely written.
There are ways of handling unexpected errors but in practice most code is written assuming it knows which exceptions might be thrown and not in anticipation for such a 'surprise'.
Given ThreadDeath is a Throwable any catch(Throwable t) will catch it and again, unless great care was taken in every piece of code the thread might execute (unrealistic) ThreadDeath might just get absorbed and not end the thread.
The correct way to handle this is declare an atomic variable (usually as part of the Runnable that represents the task.
AtomicBoolean stopThread=new AtomicBoolean(false);
Then write the loop as:
while (!stopThread.get()) {
System.out.println(1);
}
And provide a method:
public void stopThread(){
stopThread.set(true);
}
Alternatively you can use interrupt() and check interrupted(). These are cleaner methods provided in the Thread class. interrupted() has the behaviour of clearing the flag when called. That's not always helpful and while the flag can be examined by Thread.currentThread().isInterrupted() the 'checking the flag clears it' behaviour can be unhelpful and also suffers some of the issues of stop() because it can cause "surprising" exceptions to be throw at points other code has never anticipated. The right approach is to use your own flag and be in full control of where the process decides to quit.
Take your pick.
See also: Java Thread Primitive Deprecation
Ever wondered why when you click 'Cancel' on some concurrent process you are often made to wait ages for it to respond?
This is why. The task needs to come to a well defined point and do any necessary clean up to terminate in a well defined way.
Think of Thread#stop() as like stopping a cyclist by kicking them off their bike. The method here waves a red flag at them and they then come to a halt as swiftly as they safely can.
Thread#stop() should never have been in Java and you should never use it.
You get away with it in development and small systems. It causes havoc in large production environments.
It's not just deprecated as 'not recommended' it is 'inherently unsafe' do not use it.
It's been deprecated for years and its disappointing that some 'removal date' has never been advertised.
Here's an example that uses either Thread#stop() or interrupt() depending on whether you opt for being dangerous.
import java.lang.System;
import java.lang.Thread;
class Ideone
{
private static boolean beDangerous=true;//Indicates if we're going to use the Thread#stop()....
//This main method uses either stop() or interrupt() depending on the option.
public static void main (String[] args) throws java.lang.Exception
{
PrimeFactor factor=new PrimeFactor();
try{
for(int i=1;i<30;++i){
Thread thrd=new Thread(new Primer(factor));
thrd.start();
Thread.sleep(10);//Represents some concurrent processing...
if(beDangerous){
thrd.stop();
}else{
thrd.interrupt();
}
thrd.join();
if(!factor.check()){
System.out.println("Oops at "+i);
}
}
}catch(Throwable t){
System.out.println(t);
}
}
//This class just hammers the PrimeFactor object until interrupt()ed (or stop()ed).
private static class Primer implements Runnable {
private PrimeFactor factor;
public Primer(PrimeFactor ifactor){
factor=ifactor;
}
public void run(){
int i=1;
while(!Thread.interrupted()){
factor.set(i++);
}
}
}
//Don't worry about this bit too much.
//It's a class that does a non-trivial calculation and that's all we need to know.
//"You're not expected to understand this". If you don't get the joke, Google it.
//This class calculates the largest prime factor of some given number.
//Here it represents a class that ensures internal consistency using synchronized.
//But if we use Thread#stop() this apprently thread-safe class will be broken.
private static class PrimeFactor {
private long num;
private long prime;
public static long getFactor(long num){
if(num<=1){
return num;
}
long temp=num;
long factor=2;
for(int i=2;temp!=1;++i){
if(temp%i==0){
factor=i;
do{
temp=temp/i;
}while(temp%i==0);
}
}
return factor;
}
public synchronized void set(long value){
num=value;
prime=getFactor(value);
}
public synchronized boolean check(){
return prime==getFactor(num);
}
}
}
Typical partial output:
Oops at 1
Oops at 2
Oops at 3
Oops at 6
Oops at 8
Notice that the PrimeFactor class can be described as thread-safe. All it's methods are synchronized. Imagine it's in some library. It's unrealistic to expect "thread-safe" to mean Thread#stop()-safe and the only way to do that would be intrusive. Putting calls to it in a try-catch(ThreadDeath tde) block won't fix anything. The damage will have been down before it's caught.
Don't convince yourself that changing set() to the following solves it:
public synchronized void set(long value){
long temp=getFactor(value);
num=value;
prime=temp;
}
First and foremost the the ThreadDeath exception could throw during the assignments so all that does is potentially shorten the odds on the Race Condition. It hasn't been negated. Never make "how likely is that to happen" arguments about race conditions. Programs call methods billions of times so billion to one-shots come up regularly.
To use Thread#stop() you can essentially never use any library objects including java.* and jump through hoops to handle ThreadDeath everywhere in your code and almost certainly eventually fail anyway.
In java there is no official way of killing thread. This is bug. (no need to argue with it here) Thread#stop() should not be deprecated. It may be improved that it cannot be consumed. Even now it will work most of the time just fine.
Right now, if I write function which will be executed with kill need, I would start new thread and joint to it with timeout or other disconnect mechanism. This will make your code to continue like main thread was killed. Problem is that main thread is still running. All resources are still in use. This is still better than application being frozen. Calling thread.interrupt() is first step but it this does not work using thread.stop() is adequate here. It won't make things worse.
If you really must kill the thread, only way would be to start another jvm via jni, run unsafe code there and use linux kill -9 to stop the whole process if needed.
I believe killing thread is perfectly possible, only jvm developers didn't care enough. I get into this situation all the time and answers like don't use any libraries, fix all foreign code, write your own language or live with it are just frustrating.

Sending work to a pool of workers that need initialization

I have a problem that seems close to what Executors and Thread pools do, however I can't seem to make it exactly fit. Basically I have workers which take a bit of time to initialize and that I'd like to pool, and once they are ready I use them to do work. I need to do this in a Thread :
worker = buildExpensiveWorker();
worker.doWork(work1);
worker.doWork(work2);
worker.doWork(work3);
...
While an Executor only allows me to do this :
doWork(work1);
doWork(work2);
doWork(work3);
...
Will I need to write my own Thread pool ? It feels like a shame to rewrite what is already well done. Or will I need to use ThreadLocal to hold my workers, and manage them from inside the Runnable's run() method ?
If you're talking about actually initializing the Thread objects prior to them being available for use, take a look at ThreadPoolExecutor.setThreadFactory:
http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/ThreadPoolExecutor.html#setThreadFactory(java.util.concurrent.ThreadFactory)
You can provide your own implementation create a thread in any manner you want, including creating custom Thread subclasses and/or custom initialization.
I would say however, that if your initialization is expensive, you should probably try to configure the executor to keep the actual threads alive as long as possible (ie, set the keep alive time rather high, and try to spin up all the threads you need right away, and take the hit up front).
EDIT: Using a thread local (as mentioned in the comments):
public class ThreadData {
public static final ThreadLocal<String> data = new ThreadLocal<String>();
}
public class InitializingThread extends Thread {
public InitializingThread(Runnable r) {
super(r);
}
public void run() {
ThreadData.data.set("foo");
super.run();
}
}
public class InitializingThreadFactory implements ThreadFactory {
public Thread newThread(Runnable r) {
return new InitializingThread(r);
}
}
ThreadPoolExecutor executor = ...;
executor.setThreadFactory(new InitializingThreadFactory());
executor.execute(...);
And then in your Runnable:
public void run() {
String s = ThreadData.data.get();
}
Also, this approach (as opposed to using using Thread.currentThread() and casting) has the advantage of being able to actually be used with any Thread implementation (including the default), or without a thread (directly calling the .run() method after setting the value in the ThreadLocal). You could also easily change "ThreadLocal" to "InheritableThreadLocal", and set it once before submitting anything to the thread pool. All child threads would inherit the value from their parent thread (the one which created the pool).
It's important to note that the "run" method of a given thread will only ever executed once, even when in a thread pool, so this guarantees that your initialization routine happens on a per thread basis.

Java synchronized methods question

I have class with 2 synchronized methods:
class Service {
public synchronized void calc1();
public synchronized void calc2();
}
Both takes considerable time to execute. The question is would execution of these methods blocks each other. I.e. can both methods be executed in parallel in different threads?
No they can't be executed in parallel on the same service - both methods share the same monitor (i.e. this), and so if thread A is executing calc1, thread B won't be able to obtain the monitor and so won't be able to run calc2. (Note that thread B could call either method on a different instance of Service though, as it will be trying to acquire a different, unheld monitor, since the this in question would be different.)
The simplest solution (assuming you want them to run independently) would be to do something like the following using explicit monitors:
class Service {
private final Object calc1Lock = new Object();
private final Object calc2Lock = new Object();
public void calc1() {
synchronized(calc1Lock) {
// ... method body
}
}
public void calc2() {
synchronized(calc2Lock) {
// ... method body
}
}
}
The "locks" in question don't need to have any special abilities other than being Objects, and thus having a specific monitor. If you have more complex requirements that might involve trying to lock and falling back immediately, or querying who holds a lock, you can use the actual Lock objects, but for the basic case these simple Object locks are fine.
Yes, you can execute them in two different threads without messing up your class internals but no they won't run in parallel - only one of them will be executed at each time.
No, they cannot be. In this case you might use a synchronized block instead of synchronizing the whole method. Don't forget to synchronize on different objects.

calling thread.start() within its own constructor [duplicate]

This question already has answers here:
Java: starting a new thread in a constructor
(3 answers)
Closed 6 years ago.
is it legal for a thread to call this.start() inside its own constructor? and if so what potential issues can this cause? I understand that the object wont have fully initialized until the constructor has run to completion but aside from this are there any other issues?
For memory-safety reasons, you shouldn't expose a reference to an object or that object's fields to another thread from within its constructor. Assuming that your custom thread has instance variables, by starting it from within the constructor, you are guaranteed to violate the Java Memory Model guidelines. See Brian Goetz's Safe Construction Techniques for more info.
You will also see wierd issues if the Thread class is ever further subclassed. In that case, you'll end up with the thread running already once the super() exits, and anything the subclass might do in its constructor could be invalid.
#bill barksdale
If the thread is already running, calling start again gets you an IllegalThreadStateException, you don't get 2 threads.
I assume that you want to do this to make your code less verbose; instead of saying
Thread t = new CustomThread();
t.start();
activeThreads.add(t);
you can just say
activeThreads.add( new CustomThread() );
I also like having less verbosity, but I agree with the other respondents that you shouldn't do this. Specifically, it breaks the convention; anyone familiar with Java who reads the second example will assume that the thread has not been started. Worse yet, if they write their own threading code which interacts in some way with yours, then some threads will need to call start and others won't.
This may not seem compelling when you're working by yourself, but eventually you'll have to work with other people, and it's good to develop good coding habits so that you'll have an easy time working with others and code written with the standard conventions.
However, if you don't care about the conventions and hate the extra verbosity, then go ahead; this won't cause any problems, even if you try to call start multiple times by mistake.
By the way, if one wants lower verbosity and still keep the constructor with its "standard" semantics, one could create a factory method:
activeThreads.add( CustomThread.newStartedThread() );
It's legal, but not wise. The Thread part of the instance will be completely initialised, but your constructor may not. There is very little reason to extend Thread, and to pull tricks like this isn't going to help your code.
It is "legal", but I think the most important issue is this:
A class should do one thing and do it well.
If your class uses a thread internally, then the existence of that thread should not be visible in the public API. This allows improvement without affecting the public API. Solution: extend Runnable, not Thread.
If your class provides general functionality which, in this case, happens to run in a thread, then you don't want to limit yourself to always creating a thread. Same solution here: extend Runnable, not Thread.
For less verbosity I second the suggestion to use a factory method (e.g. Foo.createAndRunInThread()).
Legal ... yes (with caveats as mentioned elsewhere). Advisable ... no.
I's just a smell you can only too easily avoid. If you want your thread to auto-start, just do it like Heinz Kabutz.
public class ThreadCreationTest {
public static void main(String[] args) throws InterruptedException {
final AtomicInteger threads_created = new AtomicInteger(0);
while (true) {
final CountDownLatch latch = new CountDownLatch(1);
new Thread() {
{ start(); } // <--- Like this ... sweet and simple.
public void run() {
latch.countDown();
synchronized (this) {
System.out.println("threads created: " +
threads_created.incrementAndGet());
try {
wait();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
};
latch.await();
}
}
}

Categories

Resources