I have been working on writing a multi threaded java program. Before I progress I was thinking how best I can write the program.
I read the differences between runnable and thread and what we should use and what we should not. However I have a question. Is it good to follow the runnable implementation to thread even if the threads are not sharing data i.e the same runnable class object?
I would end up creating different runnable objects thus occupying memory.
Also another idea I have is to pool runnable objects and change the value they hold and assign it to a thread. Thereby having only a set of runnable objects and thus utilizing memory better.
Sample Code:
public class MrRunnable implements Runnable {
private String toFireUrl;
MrRunnable(String url){
}
#Override
public void run() {
// do some function here
}
}
public class Main {
public static void main(String[] args) {
// We will create 500 threads
for (int i = 0; i < 500; i++) {
Runnable task = new MrRunnable("some new url");
Thread worker = new Thread(task);
//start the thread
worker.start();
}
}
}
Here I am creating a new instance of runnable objects and my threads don't share data.
So is this way justified? Or is it better to create a pool of runnable objects and I let my threads manipulate their content and use it?
Each thread you start allocates a call stack, sized by default at 1 Megabyte. Each MrRunnable you create allocates... 24 bytes. Keeping things in perspective helps.
Related
I am pretty new to using multithreading, but I want to invoke a method asynchronously (in a separate Thread) rather than invoking it synchronously. The basic idea is that I'm creating a socket server with an object in memory, so for each client I will have to run something like object.getStuff() asynchronously.
The two constructs I found were:
having the class implement Runnable and threading this and
declaring a runnable class within a method.
Additionally this method needs a return value- will it be necessary to use Executor and Callable to achieve this? Could someone point me in the right direction for implementing this?
I have tried implement option 2, but this doesn't appear to be processing concurrently:
public class Test {
private ExecutorService exec = Executors.newFixedThreadPool(10);
public Thing getStuff(){
class Getter implements Callable<Thing>{
public Thing call(){
//do collection stuff
return Thing;
}
}
Callable<Thing> callable = new Getter();
Future<Thing> future = exec.submit(callable);
return future.get();
}
}
I am instantiating a single test object for the server and calling getStuff() for each client connection.
Threading Tutorial
The Java tutorial on concurrency has a good section on this. It's at https://docs.oracle.com/javase/tutorial/essential/concurrency/runthread.html. Essentially, you can either implement Runnable or Callable, or inherit from Thread.
Subclassing Thread
You can write a class, including an anonymous inner class, that extends Thread. Instantiate it, then invoke the start() method.
public class MyThread extends Thread {
public void run() {
System.out.println("This is a thread");
}
public static void main(String[] args) {
MyThread m = new MyThread();
m.start();
}
}
Implementing Runnable
You can write a class that implements Runnable, then wrap an instance in a Thread and invoke start(). Very much like the previous.
public class MyRunnable implements Runnable {
public void run() {
System.out.println("This is a thread");
}
public static void main(String[] args) {
MyRunnable r = new MyRunnable();
(new Thread(r)).start();
}
}
Return Value
Runnable doesn't allow for return values. If you need that, you need to implement Callable instead. Callable looks a lot like Runnable, except you override the call() method instead of the run() method, and you need to give it to an ExecutorService.
public class MyCallable implements Callable<Integer> {
public Integer call() {
System.out.println("A thread using Callable<Integer>");
return 42;
}
public static void main(String[] args) {
MyCallable c = new MyCallable();
Future<Integer> f = Executors.newSingleThreadExecutor().submit(c));
System.out.println("The thread returned: " +
f.get());
}
}
The two constructs I found were 1) having the class implement Runnable and threading 'this' and 2) declaring a runnable class within a method.
Option (2) probably is better. Most programs would be improved if they had more classes, not fewer. Each named entity in a program—each package, class, method, whatever—should have just one responsibility. In your option (1), you are asking the class to do two things.
For your option (2), you don't actually have to declare a whole class. You can either use an anonymous inner class, or if you can go with Java8 all the way, you can use a lambda expression. Google for either one to learn more.
Additionally this method needs a return value.
The classic way, is for the Runnable object to return the value through one of its own fields before the thread terminates. Then the parent thread, can examine the object and get the return value afterward.
Will it be necessary to use Executor and Callable to achieve this?
Necessary? A lot of people think that ExecutorService is a Good Thing.
Sounds like you are creating a server that serves multiple clients. Do these clients continually connect and disconnect? The advantage of using a thread pool (i.e., ThreadPoolExecutor) is that it saves your program from continually creating and destroying threads (e.g., every time a client connects/disconnects). Creating and destroying threads is expensive. If you have a lot of clients connecting and disconnecting, then using a thread pool could make a big difference in the performance of your server.
Creating and managing threads by yourself is generally bad approach.
As you already pointed - use Executors utility class to create executor and submit Callables to it.
public class RunWResult implements Runable{
private volatile ResultType var;
//the thread method
public void run(){
...
//generate a result and save it to var
var = someResult();
//notify waiting threads that a result has been generated
synchronized(this){
notify();
}
}
public ResultType runWithResult(){
//run the thread generating a result
Thread t = new Thread(this);
t.start();
//wait for t to create a result
try{
wait();
}catch(InterruptedException e){}
//return the result
return var;
}
}
This question already has answers here:
Initializing two threads with the same instance of a runnable
(4 answers)
Passing single runnable object to multiple thread constructors [duplicate]
(2 answers)
Closed 9 years ago.
When we call start() on a Thread by passing a Runnable object as argument, can we pass the same Runnable reference to start multiple threads?
public class MyMain {
public static void main(String[] args) {
MyRunnableImpl impl = new MyRunnableImpl();
new Thread(impl).start();
new Thread(impl).start();
}
}
Yes, you can do this when your Runnable is implemented accordingly.
But you have to be careful your Runnable implementation does not contain a mutable state. You can control this in your own implementations, but the Runnable contract does not specify.
// can be used for multiple Threads
class StatelessRunnable {
public void run() {
doSomething();
}
}
// may go bang on the second execution -> use two instances
class StatefulRunnable {
volatile boolean canRun = true;
public void run() {
if(!canRun) throw new IllegalStateException();
canRun = false;
}
}
In the above sample you see that you can use StatelessRunnable for as many threads as you like. In fact you could even make it a singleton. StatefulRunnable in contrast can be run only once per instance.
Shared State
Reading Jon's answer I realised there may be scenarios where you actually want to share a state of two Runnable instances. Of course a stateful Runnable instance is not always bound to fail with multiple threads, but this is much more trickier to get right than a stateless one.
// willingly share state over threads
class WillinglyStatefulRunnable {
final BlockingQueue<Object> sharedObjects = new BlockingQueue<Object>();
public void run() {
sharedObjects.offer(new Object());
}
}
The above example shows how you could work on a single collection sharedObjects with multiple threads.
Literature Sidenote:
Item 15 in Joshau Bloch's Effective Java says Minimize Mutabilty. This chapter - in case you have access to the book - addresses similar points in a much more general context. Shortly summarised he states that immutable objects make it easier to reuse instances and reduce the potential of illegal states.
Suppose I have a class which implements Runnable interface, and I am to make 5 instances of given class in the main program. I would like to store them either in array, or a collection. Since the class implements Runnable it is my understanding that the only way I can store it is in a thread container such as Thread[]. However if I do this I can't use classes overridden toString() method for example, or any other custom method/field.
public class LittleClass implements Runnable{
public void run(){
}
}
public static void main(String[] args){
Thread[] smallClasses = new Thread[5];
// initialize and so...
smallClasses[i].customField//not accessible
System.out.println(smallClasses[i])//gives Thread[Thread-X,X,]
}
You should consider using an ExecutorService. Then you keep an array of your job classes and submit them to the service to be run.
// create a thread pool with as many workers as needed
ExecutorService threadPool = Executors.newCachedThreadPool();
// submit your jobs which should implements Runnable
for (YourRunnable job : jobs) {
threadPool.submit(job);
}
Once you have submitting your jobs, you shut down the service, wait for it to finish, and then you can interrogate your jobs to get information from them.
// shuts the pool down but the submitted jobs still run
threadPool.shutdown();
// wait for all of the jobs to finish
threadPool.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
// now go back and print out your jobs
for (YourRunnable job : jobs) {
System.out.println(jobs.toString());
}
Here's a good tutorial on the subject.
You can create your custom class which implements Runnable and then story an array of those custom classes.
So, for instance, in the code you wrote above, you can always use
LittleClass[] objs = new LittleClass[4];
for(int i = 0; i < objs.length; i++) {
objs[i] = new LittleClass();
}
Is it bad programming to initialize two threads with the same instance of a runnable? What difference would it make to initialize with separate instances of a runnable, and does sharing memory locations at all for the same instance of a runnable have anything to do with performance?
public static void main(String[] args)throws Exception {
H h = new H();
H h2 = new H();
Thread j = new Thread(h);
j.setName("11");
Thread jj = new Thread(h);//instead of new H()
jj.setName("22");
j.start();
jj.start();
}
class H implements Runnable {
public void run() {
while(true) {
System.out.println(Thread.currentThread().getName());
}
}
}
It's absolutely fine to do it so long as the code you're running is designed to support that. Not only will it save some memory by having a single instance instead of multiple instances, but if those threads are trying to communicate via shared data, then it may be absolutely required!
Admittedly communicating via shared state is where threading often gets tricky, so this needs to be done carefully, but from the point of view of the threading system itself, there's absolutely no problem in having two threads call the run method of a single Runnable instance.
Since H doesn't have any instance state, using multiple instances won't matter. You need to take care when the Runnable instances start storing state.
public class Main implements Runnable {
volatile int i;
public void run() {
for (i = 0; i < 100; i++) {
System.out.println(i);
}
}
public static void main(String[] args) {
Main a = new Main();
Thread t1 = new Thread(a);
Thread t2 = new Thread(a);
t1.start();
t2.start();
}
}
What gets printed? When you do need to share state between threads, it's a good idea to use the classes in java.util.concurrent. They were written primarily by an expert in multithreading (Doug Lea, author of Concurrent Programming in Java) and tested by many people. Save yourself some heartache. :)
Is it bad programming to initialize two threads with the same instance of a runnable?
Not specifically. However, if the Runnable instance has instance fields, then you'll need to make sure that all access to the fields by the thread is properly synchronized, and this will make the code more complicated.
What difference would it make to initialize with separate instances of a runnable, and does sharing memory locations at all for the same instance of a runnable have anything to do with performance?
The memory saved by sharing a Runnable instance between multiple threads is insignificant ... unless the Runnable holds a significant amount of instance data. (And if it does, the chances are that this will make the instance non-shareable.)
Your H class is an example where sharing instances is safe, but pointless since the memory saving is insignificant. (A Runnable object with no instance fields occupies roughly 8 to 16 bytes, depending on the platform.)
To make understand easily(based on the comment of Stephen), added the below program block about the impact of accessing the instance variable from a non-synchronized block with the same instance of Runnable displays the unexpected results.
public class SynchronizedInstanceMethod implements Runnable{
private int counter;
public SynchronizedInstanceMethod(int counterValue){
this.counter = counterValue;
}
private synchronized void displayMessage(){
System.out.println(" Display Message ");
}
private void modifyCounter(){
this.counter++;
System.out.println("Value -- "+ this.counter);
}
#Override
public void run() {
this.displayMessage();
this.modifyCounter();
}
public static void main(String[] args) {
SynchronizedInstanceMethod instance = new SynchronizedInstanceMethod(5);
new Thread(instance).start();
new Thread(instance).start();
}
}
I have one Runnable that is used by more than one thread:
Runnable myRunnable = new MyWorker();
Thread one = new Thread(myRunnable);
Thread two = new Thread(myRunnable);
one.start();
two.start();
How can I get all threads that are created with myRunnable?
(Of course the example is simplified. I create new threads with myRunnable on several places in different classes.)
Use case (as requested): MyWorkerOfMyPage is a delayed worker that is bound to a page. If the user leaves this page (e.g. by navigating to another page) all threads that belong to MyWorkerOfMyPage should be killed ungracefully as their result is not needed anymore.
As already said best way is to track this yourself. This forces you to get a clear understanding of what you are doing. A good thing if you work with threads ... hmmm ... a good thing in every case ;).
But if you realy want to detect the threads you can use reflection with the Thread class to get the required information. First make the method "getThreads" accessible to get all running Threads, then make the field "target" accessible to get the runnables of the Threads.
Heres an example program (but I would advise against the usage in a real application. You should now what threads you are starting, it might harm compability with future JDKs, might harm portability ...):
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) throws Exception {
Runnable myRunnable = new Runnable() {
#Override
public void run() {
try {
System.out.println("Start: " + Thread.currentThread().getName());
Thread.sleep(100);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
};
Thread one = new Thread(myRunnable);
Thread two = new Thread(myRunnable);
one.start();
two.start();
List<Thread> threads = getThreadsFor(myRunnable);
for (Thread thread : threads)
System.out.println("Found: " + thread.getName());
}
private static List<Thread> getThreadsFor(Runnable myRunnable) throws Exception {
Method getThreads = Thread.class.getDeclaredMethod("getThreads");
Field target = Thread.class.getDeclaredField("target");
target.setAccessible(true);
getThreads.setAccessible(true);
Thread[] threads = (Thread[]) getThreads.invoke(null);
List<Thread> result = new ArrayList<Thread>();
for (Thread thread : threads) {
Object runnable = target.get(thread);
if (runnable == myRunnable)
result.add(thread);
}
return result;
}
}
The best way to do this is to track this yourself. Use a global singleton for instance that launches the threads and track which ones you started.
Although my first thoughts are along #Bengt's lines, perhaps you could use Class.isAssignableFrom if you had a list of runnables and you just want to know which ones use your interface.
http://download.oracle.com/javase/6/docs/api/java/lang/Class.html
In Java there is no simple way to find all the places a object is referenced, its something you have to maintain a collection of yourself.
If you want to know this staticly you can Find Usages in your ide.
If you want to know this dynamically you can have the Runnable add the Thread to a collection (and remove it when finished)
Generally speaking, the developer should only create Threads deliberately. i.e. the Developer should know when he/she is creating thread and what those threads will be doing. Its not something you should be trying to track at runtime if you have a good design.