I'm trying to figure out how to multithread in java. Right now, my program works fine with no concurrency but I want to implement multithreading to help speed it along.
The program runs several objects of a separate sub class and 50% of the time evaluation for each of those objects is spent in a process which only utilizes one core rather than the 8 available. These objects are completely independent of one another until but are used as inputs in the program.
I am trying to multithread this by having the subclass implement Runnable and then have my program use a thread for each such object. Would this be the correct way?
However, how are threads in java handeled? Would I need to dispose of the threads after each run? How does join work?
thanks
Don't manage threads manually, take a look at executors and thread pools in java
You're pretty much on track. You'll create a Thread object
Runnable r = new MyClassImplementingRunnable();
Thread t = new Thread(p);
t.start();
t.join(); // wait for thread to die
The Thread object is garbage collected like any other object, the thread itself dies when the run method completes. The key thing is that your Runnable's run method really must guarantee to return, your design cannot depend on being able to kill thread from the outside.
If you are going to have lots of threads you need to wait for them all to finish, so you can either keep a collection of the threads you've started and then use t.join( smallNumberOfMillis) to see which of them has finished. That's a little inefficient so there are other techniques for allowing threads to communicate with each other, I'd suggest reading this article about them.
#denis also mentions that the Executor and related classes provides a nicer abstraction above Threads. If you have an interest in learning the background then manually managing Threads is interesting. If you just want to get the job done, follow Denis' suggestion.
Take a look at http://download.oracle.com/javase/1,5.0/docs/api/java/util/concurrent/ScheduledThreadPoolExecutor.html
The constructor takes the number of threads you want. In this case the same as your number of cores.
ScheduledThreadPoolExecutor s = new ScheduledThreadPoolExecutor(8);
List<Future> futures = new ArrayList<Future>();
foreach(...something...)
futures.add(s.submit(new MyCallable()));
foreach(Future f : futures)
f.get(); // Result of computation
System.out.println("Done");
This is a good way to start multithreading.
public class ThreadExample {
public static void main(String[] args) {
//Main thread
System.out.println("Main thread");
new Thread(new Runnable() {
#Override
public void run() {
//This thread is independent of the main thread
System.out.println("Inner Thread");
}
}).start();
}
}
Related
I have a class Prefs, which has various methods. I need to rewrite it using threading and synchronization.
I'm looking at this variant: http://tutorials.jenkov.com/java-concurrency/synchronized.html
So currently:
class T_readConfigFile extends Thread {
protected Prefs p = null;
public T_readConfigFile(Prefs p) {
this.p =p;
}
public void run() {
p.readConfigFile();
}
}
and
public synchronized void readConfigFile() { ...
But somehow making N identical classes for each of the methods I want to thread doesn't look like a good idea. I assume it the entire class in this.p = p; gets loaded into memory — do I really need that if I'll be using only one method from there?
So: this works, but I don't like it, are there better ways?
Suppose you want to call some method foo() in a background thread. You have already discovered the most basic way. Here's a somewhat preferable variation on what you did:
new Thread(new Runnable() {
#Override
public void run() {
foo();
}
}).start();
OK, so I wrote six lines of Java code to call one function. Yes, that's kind of verbose. Welcome to Java (or at least, Welcome to Java7. If it can be done more concisely in Java8, I haven't yet learned how.)
This approach has a couple of problems that are worse than verbosity though:
1) You create and destroy a new thread each time you want to call a background method. Creating and destroying threads is relatively expensive.
2) If the background tasks take significant time to perform relative to how often you invoke them, you have no means to control the number of them that are running at the same time. In a busy application, it could keep growing until you get an OutOfMemoryError.
A better approach is to use a thread pool:
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
...
final int NUM_THREADS = ...;
final ExecutorService executorService = Executors.newFixedThreadPool(NUM_THREADS);
...
executorService.submit(new Runnable() {
#Override
public void run() {
foo();
}
});
Each time you submit a new task to the thread pool, it will wake an already existing thread, and the thread will perform the task and then go back to sleep. No threads are created or destroyed except when the pool starts up.
Also, if all of the threads are busy when you submit the new task, the task will be added to a queue, and it will be performed later when a worker thread becomes available.
This is just a simple example: The java.util.concurrent package gives you many more options including the ability to limit the size of the queue, the ability to make thread pools that grow or shrink depending on demans, and perhaps most important of all, the ability to wait for a task to complete, and a way to get a return value from a completed task.
Check it out. http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/package-frame.html
A synchronized method locks the method's class object so that only one thread can be executing that method at a time. This is useful for situations where you don't want multiple threads to be reading or writing to the same file or stream at the same time, for example.
If you need each thread to read its own separate configuration file, you probably don't need to synchronize the readConfigFile() method. On the other hand, you do need to synchronize it if every thread reads the same config file.
But if all of the threads are reading the same config file, perhaps you should only have one thread (or perhaps the main parent thread) read the file once, and then pass the resulting parsed config values to each thread. This saves a lot of I/O.
I have a Thread which runs my game loop. I want to be able to run this game loop each time I start a new game. But since the threads in Java can only be started once, how can I do this?
Create a new Thread around the same Runnable instance and start that.
Since you want the Thread that runs the game loop to keep running it, you need to code it something like this:
public class GameLoop implements Runnable {
...
public void run() {
while (gameNotFinished) {
// do stuff
}
}
}
If that is not working, then the chances are that the run() method is dying because of an exception that you are not catching / logging, and therefore not noticing.
1. When you say that "you need to run a thread", i means you want to start a sub-task on a separate thread.
2. Now if you mean this certain sub-task, then please prefer to run a new thread.
3. As you said But since the threads in Java can only be started once
This means that when a thread (thread of execution) completes its run() method, then the Thread object associated with it permanently looses its threadness, right....
But if this thread is from a pool, then the pool itself manages the Thread objects and its reused. Try using Executors from java.util.concurrent package.
1) The short answer is precisely what SLaks already said: just "...create a new thread around the same runnable instance and start that."
2) I think you might be confused about the distinction between the everyday meaning of "start", and the semantics of the Java Thread method "start()". This tutorial might help:
http://www.geom.uiuc.edu/~daeron/docs/javaguide/java/threads/states.html
3) Should you wish to re-use the same thread, you can use the methods "wait()" and "resume()":
http://www.javabeginner.com/learn-java/java-threads-tutorial
I have a requirement to run a thread in background in java and may need to pass some information to the thread before it starts doing its actual function.
How to implement this?
Secondly, is it possible to start a thread which does further operation and exit from request context. Please note that I have to implement in a web application.
An example to answer your first question:
class NewThread extends Thread
{
public String someInformation;
#Override
public void run()
{
System.out.println(someInformation);
}
}
public class YourClass
{
public void startANewThread()
{
NewThread newThread = new NewThread();
newThread.someInformation = "hello";
newThread.start();
}
}
As for your second question: This code should run in a web application, but you must be extremely careful to make sure, that these background Threads will finish at some point, or else that would be a nice little memory leak.
Please note, that if you want to share information when both Threads are running, you need to synchronize information access.
Depending on what the background Thread does it might make sense to use a framework like Quartz
is it possible to start a thread which does further operation and exit from request context. Please note that I have to implement in a web application.
You can use an ExecutorService to pass any number of tasks to and shutdown when you have finished with it.
Try this block of code, with two threads, where one thread will run in background and another thread will start executing the task. And here you can set a return type as well unlike thread.run() method.
FutureTask<Response> future = new FutureTask<>(newCallable<Response>() {
public yourreturntype call() {
doSomething(Thread1);
}
});
ExecutorService executor = Executors.newSingleThreadExecutor();
executor.execute(future);
doSomethingelse(Thread2)
//This thread doesnot wait for thread1 to complete
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Java: “implements Runnable” vs. “extends Thread”
I'm just wondering is there some subtle difference between creating your own custom object that extends Thread and creating a thread using the Thread(Runnable) constructor?
I have some code that works fine when I use classes that extend Thread, but if I try to use logic that creates Threads by using the Thread(Runnable) constructor the new threads do not seem to work properly - I can't detect that they are alive in the same way as when I use the custom sub-classes I made and they do not seem to end, ever.
In my code I'm just spawning a few threads then searching through my list of threads to find one that is alive and joining with it until it dies. Then I once again search for a thread in the list that is alive and join to it.. this continues until all threads die.
Thanks for reading.
A Thread is a resource for doing work. A Runnable is a piece of work. Are you creating a new type of resource, or just defining the work you want done?
To 'end' the thread you simply return from the 'run' method. Would need to see an example of your code to see what you mean about not being able to tell if they're active.
Creating Runnables also of course makes it easier to refactor your code to use a ThreadPool in the future.
In my code I'm just spawning a few threads then searching through my list of threads to find one that is alive and joining with it until it dies.
How (and why) are you "searching through my list of threads"? I would instead add the Thread to some sort of Collection that you then can then iterate across and join with each Thread in turn:
List<Thread> threads = new ArrayList<Thread();
for (int i = 0; i < 100; i++) {
Thread thread = new Thread(new Runnable() ...);
thread.start();
threads.add(thread);
}
...
for (Thread thread : threads) {
thread.join();
}
Even better would be to use one of the ExecutorServices given by Executors. They have a lot of features around creating thread-pools and waiting for the pool to completely finish. Almost always recommended over new Thread(...).
I can't detect that they are alive in the same way as when I use the custom sub-classes I made
If you are trying to set the name of the Thread then you can't do this in the constructor of your Runnable. You can however do this in the run() method. You can do:
new Thread(new Runnable() {
public void run() {
Thread.currentThread().setName("...");
}
});
Otherwise, I'm not sure why you wouldn't be seeing your Thread unless it has already finished.
they do not seem to end, ever.
Using a Runnable, the thread finishes when the run() method returns -- either through a return or a throw. This is very much the same as extending Thread so I'm not sure why this wouldn't work.
I would really recommend to use the concurrency utility and not trying to manage yourself the Threads, which is complicated and error prone.
Using the concurrent api will also help you to apply the right patterns straight away.
I am storing a bunch of threads objects in an arraylist. I want to be able to start these threads at random. Same thread can be started more than once. Before I start a thread object, I check on whether the thread is alive, and if they have either of NEW or TERMINATED status. This restriction because, I don't want to disturb the 'busy' threads. Now, for NEW threads, this works fine. But for TERMINATED thread, I get an exception.
When a thread ends, shouldn't it go back to being 'new'? Or are threads 'disposable' - like use once and done?
As it says in the documentation for Thread.start(), "It is never legal to start a thread more than once. In particular, a thread may not be restarted once it has completed execution."
It is better for you to keep hold of Runnable instances and implement your own logic for keeping track of when the execution of each one of them finishes. Using an Executor is probably the simplest way to run the Runnables.
You should probably be using the awesome stuff provided in java.util.concurrent. Based on your description, ThreadPoolExecutor sounds like a good thing to check out.
This is the way I did it
class GarbageDisposalThread extends Thread {
public void start() {
try {
super.start();
} catch( IllegalThreadStateException e ) {
this.arrayList.remove(this);
this.arrayList.add( new GarbageDisposalThread( this.arrayList ));
}
}
private GarbageDisposalThread() {
}
public GarbageDisposalThread( ArrayList<Whatever> arrayList ) {
this.arrayList = arrayList;
this.start();
}
public void run() {
// whatever the code
}
private ArrayList<Whatever> arrayList = null;
}
that's it!
you can change the code according to your needs :P
Java threads cannot be restarted.
From the javadoc:
It is never legal to start a thread
more than once. In particular, a
thread may not be restarted once it
has completed execution.
See the Thread.start() javadoc for more information.
There are other ways to accomplish what you are trying to do. For example, you could use new Threads that continue the work that was done in the Thread that has finished execution. You may also want to investigate the java.util.concurrent package.
From another post...
You could use ThreadPoolExecutor, which would allow you to pass in tasks and let the service assign a thread to a task. When the task is finished, the thread goes idle until it gets the next task.
So, you don't restart a thread, but you would redo/resume a task.