I want to spawn a Java thread from my main java program and that thread should execute separately without interfering with the main program. Here is how it should be:
Main program initiated by the user
Does some business work and should create a new thread that could handle the background process
As soon as the thread is created, the main program shouldn't wait till the spawned thread completes. In fact it should be seamless..
One straight-forward way is to manually spawn the thread yourself:
public static void main(String[] args) {
Runnable r = new Runnable() {
public void run() {
runYourBackgroundTaskHere();
}
};
new Thread(r).start();
//this line will execute immediately, not waiting for your task to complete
}
Alternatively, if you need to spawn more than one thread or need to do it repeatedly, you can use the higher level concurrent API and an executor service:
public static void main(String[] args) {
Runnable r = new Runnable() {
public void run() {
runYourBackgroundTaskHere();
}
};
ExecutorService executor = Executors.newCachedThreadPool();
executor.submit(r);
// this line will execute immediately, not waiting for your task to complete
executor.shutDown(); // tell executor no more work is coming
// this line will also execute without waiting for the task to finish
}
Even Simpler, using Lambda! (Java 8) Yes, this really does work and I'm surprised no one has mentioned it.
new Thread(() -> {
//run background code here
}).start();
This is another way of creating a thread using an anonymous inner class.
public class AnonThread {
public static void main(String[] args) {
System.out.println("Main thread");
new Thread(new Runnable() {
#Override
public void run() {
System.out.println("Inner Thread");
}
}).start();
}
}
And if you like to do it the Java 8 way, you can do it as simple as this:
public class Java8Thread {
public static void main(String[] args) {
System.out.println("Main thread");
new Thread(this::myBackgroundTask).start();
}
private void myBackgroundTask() {
System.out.println("Inner Thread");
}
}
Related
I have the following piece of code which I expected to print "DONE" at the end. But when I ran, "DONE" was never printed and the JVM in fact never terminated.
What did I do wrong?
// File: Simple.java
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class Simple {
public static void main(String[] args) throws Exception{
doTest(3);
}
private static void doTest(final int times) {
ScheduledExecutorService tp = Executors.newScheduledThreadPool(times);
Thread[] runnables = new Thread[times];
for (int i = 0; i < runnables.length; ++i) {
runnables[i] = new Thread(new MyRunnable());
}
// schedule for them all to run
for (Thread t : runnables) {
tp.schedule(t, 1, TimeUnit.SECONDS);
}
try {
tp.awaitTermination(Long.MAX_VALUE, TimeUnit.SECONDS);
System.out.println("DONE!");
}catch (InterruptedException e) {
e.printStackTrace();
}
}
static class MyRunnable implements Runnable {
#Override
public void run() {
System.out.println("hello world");
}
}
}
There are two things that you're doing wrong here.
First off, if you're using an ExecutorService, you shouldn't then also be creating your own threads. Just submit Runnables to the executor directly - the executor service has its own collection of threads, and runs anything you submit on its own threads, so the threads you created won't even get started.
Second, if you're done with an ExecutorService, and are going to wait until it's terminated, you need to call shutdown() on the executor service after you submit your last job.
Executors.newScheduledThreadPool(times) uses Executors.defaultThreadFactory() for its ThreadFactory.
Here is the documentation
When a Java Virtual Machine starts up, there is usually a single
non-daemon thread (which typically calls the method named main of some
designated class). The Java Virtual Machine continues to execute
threads until either of the following occurs:
The exit method of class Runtime has been called and the security manager has permitted the exit operation to take place.
All threads that are not daemon threads have died, either by returning from the call to the run method or by throwing an exception
that propagates beyond the run method.
So, here is what you had; but I changed 3 things.
Added the shutdown hook
Made the schedule delayed by an extra second for each to demo that the shutdown is being called even before some of the threads are being called to run by the scheduler.
Lastly, you were telling it to wait forever using the Long.MAX. But I think you were doing it because the shutdown feels like it would shutdown now. But it won't.
public static void main(String[] args) throws Exception {
doTest(3);
}
private static void doTest(final int times) {
ScheduledExecutorService tp = Executors.newScheduledThreadPool(times);
Thread[] runnables = new Thread[times];
for (int i = 0; i < runnables.length; ++i) {
runnables[i] = new Thread(new MyRunnable());
}
// schedule for them all to run
int i = 1;
for (Thread t : runnables) {
tp.schedule(t, i++, TimeUnit.SECONDS);
}
System.out.println("Calling shutdown");
tp.shutdown();
}
static class MyRunnable implements Runnable {
#Override
public void run() {
System.out.println("hello world");
}
}
Hope that answers your question. Now, you're kinda duplicating stuff.
If you are going to use the executerservice, you should just tell it to schedule stuff for you.
public static void main(String[] args) throws Exception {
doTest(3);
}
private static void doTest(final int times) {
ScheduledExecutorService tp = Executors.newScheduledThreadPool(times);
for (int i = 0; i < times; ++i) {
tp.schedule(new MyRunnable(), 1, TimeUnit.SECONDS);
}
System.out.println("Calling shutdown");
tp.shutdown();
}
static class MyRunnable implements Runnable {
#Override
public void run() {
System.out.println("hello world");
}
}
You forgot to shutdown your ExecutorService:
tp.shutdown(); // <-- add this
tp.awaitTermination(Long.MAX_VALUE, TimeUnit.SECONDS);
Also I should mention that creating Threads to use them as Runnables is not only meaningless, but can be misleading as well. You should really use Runnable instead of Thread for runnables variable.
Runnable[] runnables = new Runnable[times];
I'm a Java learner, trying to understand Threads.
I was expecting output from my program below, in the order
Thread started Run Method Bye
But I get output in the order
Bye Thread started Run Method
Here is my code:
public class RunnableThread
{
public static void main(String[] args)
{
MyThread t1= new MyThread("Thread started");
Thread firstThread= new Thread(t1);
firstThread.start();
System.out.println("Bye");
}
}
class MyThread implements Runnable
{
Thread t;
String s= null;
MyThread(String str)
{
s=str;
}
public void run()
{
System.out.println(s);
System.out.println("Run Method");
}
}
In a multithreaded code there's no guarantee which thread will run in what order. That's in the core of multithreading and not restricted to Java. You may get the order t1, t2, t3 one time, t3, t1, t2 on another etc.
In your case there are 2 threads. One is main thread and the other one is firstThread. It's not determined which will execute first.
This is the whole point of Threads - they run simultaneously (if your processor has only one core though, it's pseudo-simultaneous, but to programmer there is no difference).
When you call Thread.start() method on a Thread object it's similar (but not the same, as it's starting a thread, and not a process and former is much more resource consuming) simultaneously starting another java program. So firstThread.start() starts to run paralel to your main thread (which was launched by your main method).
This line starts a main execution thread (like a zeroThread)
public static void main(String[] args)
Which you can reference, by calling Thread.sleep() for example.
This line
firstThread.start();
Starts another thread, but in order to reference it you use it's name, but you reference it from the main thread, which is running paralel to firstThread.
In order to get the expected output you can join these two threads, which is like chaining them:
This way:
public static void main(String[] args)
{
MyThread t1= new MyThread("Thread started");
Thread firstThread= new Thread(t1);
firstThread.start();
firstThread.join();
System.out.println("Bye");
}
join(), called on firstThread (by main thread) forces main thread to wait until the firstThread is finished running (it will suspend proceding to the next command, which is System.out.println("Bye");).
It appears that you seek the thread (and probably more than one) to run while main() waits for everything to finish up. The ExecutorService provides a nice way to manage this -- including the ability to bail out after a time threshold.
import java.util.concurrent.*;
class MyThread implements Runnable { // ... }
class MyProgram {
public static void main(String[] args)
{
MyThread t1 = new MyThread();
MyThread t2 = new MyThread();
MyThread t3 = new MyThread();
// At this point, 3 threads teed up but not running yet
ExecutorService es = Executors.newCachedThreadPool();
es.execute(t1);
es.execute(t2);
es.execute(t3);
// All three threads now running async
// Allow all threads to run to completion ("orderly shutdown")
es.shutdown();
// Wait for them all to end, up to 60 minutes. If they do not
// finish before then, the function will unblock and return false:
boolean finshed = es.awaitTermination(60, TimeUnit.MINUTES);
System.out.println("Bye");
}
}
There is no specified order in which Java threads are accustomed to run. This applies for all threads including the "main" thread.
If you really want to see it working, try:
class RunnableThread
{
public static void main(String[] args)
{
MyThread t1= new MyThread();
Thread firstThread= new Thread(t1);
firstThread.start();
System.out.println("Thread Main");
for(int i=1;i<=5;i++)
{
System.out.println("From thread Main i = " + i);
}
System.out.println("Exit from Main");
}
}
class MyThread implements Runnable
{
public void run()
{
System.out.println("Thread MyThread");
for(int i=1;i<=5;i++)
{
System.out.println("From thread MyThread i = " + i);
}
System.out.println("Exit from MyThread");
}
}
When You start a Thread it will execute in parallel to the current one, so there's no guarantee about execution order.
Try something along the lines:
public class RunnableThread {
static class MyThread implements Runnable {
Thread t;
String s= null;
MyThread(String str) {
s=str;
}
public void run() {
System.out.println(s);
System.out.println("Run Method");
}
}
public static void main(String[] args) {
MyThread t1= new MyThread("Thread started");
Thread firstThread= new Thread(t1);
firstThread.start();
boolean joined = false;
while (!joined)
try {
firstThread.join();
joined = true;
} catch (InterruptedException e) {}
System.out.println("Bye");
}
}
This is not a thread start order problem. Since you're really only starting a single thread.
This is really more of an API Call speed issue.
Basically, you have a single println() printing "bye", which gets called as soon as the Thread.start() returns. Thread.start() returns immediately after being called. Not waiting for the run() call to be completed.
So you're racing "println" and thread initializaiton after "thread.start()", and println is winning.
As a sidenote, and in general, you might want to try to use ExecutorService and Callable when you can, as these are higher level, newer APIs.
I have a thread in Java that makes a web call and stores the information retrieved, but it only retrieves information for that particular instant. I'd like to run this thread every second for a certain period of time to get a better view of the data. How can I do this? I've looked at ScheduledExecutorService, and from what I can tell if the thread is still running when it's time to set up the next run, it waits until the first thread is complete, which isn't what I'm looking for.
You can do this by a double schedule. Use scheduleWithFixedDelay() to set off a job every second. This job starts the method which you really want to run. Here is some code based on Oracle's ScheduledExecutorService API.
The Thread.sleep() is there to simulate a long-running task.
class Beeper {
public static void main(String[] args) {
(new Beeper()).beep();
}
private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
public void beep() {
final Runnable beeper = new Runnable() {
public void run() {
System.out.println("beep");
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
final Runnable beeper2 = new Runnable() {
public void run() {
(new Thread(beeper)).start();
}
};
final ScheduledFuture<?> beeperHandle = scheduler.scheduleAtFixedRate(beeper2, 1, 1, SECONDS);
}
}
What you need is the scheduleAtFixedRate method: http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ScheduledExecutorService.html#scheduleAtFixedRate(java.lang.Runnable,%20long,%20long,%20java.util.concurrent.TimeUnit)
When the scheduler waits until the first thread is complete, it's because you're using scheduleWithFixedDelay.
However, if you absolutely want the threads run concurrently, you should try this:
pool.scheduleAtFixedRate(new Runnable() {
#Override
public void run() {
pool.submit(myJob);
}
}, 1, 1, TimeUnit.SECONDS);
I advise to always use a pool.
What about this?
public static void main (String [] args) throws InterruptedException{
ExecutorService executorService =
Executors.newFixedThreadPool(10);
while (true){
executorService.submit(new Runnable() {
#Override
public void run() {
// do your work here..
System.out.println("Executed!");
}});
Thread.sleep(1000);
}
}
I a trying to find out, after complete first thread completely than start second thread, after complete second thread than start third thread, Please help me!!
Here is my code:
public class wait {
/**
* #param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println("First Thread");
createtheard2();
}
public static void createtheard2() {
try {
System.out.println("Second Thread");
} catch(Exception error1) {
error1.printStackTrace();
}
createtheard3();
}
public static void createtheard3() {
try {
System.out.println("Third Thread");
} catch(Exception error1) {
error1.printStackTrace();
}
}
}
After complete first thread, than start second thread, after complete second thread, than start third thread, Please help me!! Thanks!!
Implement Runnable
public class ThreadDemo implements Runnable {
public void run() {
//Do this what you need
}
}
Use join to wait while thread will be completed.
Thread t1 = new Thread(new ThreadDemo());
// this will call run() function
t1.start();
// waits for this thread to die
t1.join();
Thread t2 = new Thread(new ThreadDemo());
// this will call run() function
t2.start();
// waits for this thread to die
t2.join();
From http://docs.oracle.com/javase/tutorial/essential/concurrency/join.html
t.join() causes the current thread to pause execution until t's
thread terminates.
In your case paused by join method invocation thread will be Main thread.
I think what you need is if task 1 (thread in your terms) success, run task2 else wait for task1. consider the following.
public class Process{
public static void runProcess1() {
boolean done = false;
do {
// make done=true after task1 is done
} while (done);
runProcess2();
}
public static void runProcess2() {
boolean done = false;
do {
// make done=true after task2 is done
} while (done);
runProcess3();
}
public static void main(String[] args) {
runProcess1();
}
}
As it was pointed out, using threads in this case does not make sense as you are executing tasks sequentially.
However, it is possible to have a single thread running at a time with SingleThreadExecutor
For example, you
Add your threads to a "todo list" (ArrayList will do the job)
Schedule a task (ExecutorService.execute())
Wait for the scheduled task to complete (Thread.join())
Drop the thread from the "todo list" tasks.remove(currentTask);
Pick the next task or go to step 7 if all has been finished
Go back to step 2
Kill the ExecutorService (ExecutorService.shutdown())
Alternatively, you could use ExecutorService.invokeAll() using a single thread executor.
You could even simply run the tasks directly in a loop, invoking start(), however, I'd really recommend against using concurrency where it is not a necessity.
I want to know the best way how to notify another thread. For example, I have a background thread:
public void StartBackgroundThread(){
new Thread(new Runnable() {
#Override
public void run() {
//Do something big...
//THEN HOW TO NOTIFY MAIN THREAD?
}
}).start();
}
When it finished it has to notify main thread? If somebody knows the best way how to do this I'll appreciate it!
The typical answer is a BlockingQueue. Both BackgroundThread (often called the Producer) and MainThread (often called the Consumer) share a single instance of the queue (perhaps they get it when they are instantiated). BackgroundThread calls queue.put(message) each time it has a new message and MainThread calls 'queue.take()which will block until there's a message to receive. You can get fancy with timeouts and peeking but typically people want aBlockingQueueinstance such asArrayBlockingQueue`.
Purely based on your question you could do this:
public class test
{
Object syncObj = new Object();
public static void main(String args[])
{
new test();
}
public test()
{
startBackgroundThread();
System.out.println("Main thread waiting...");
try
{
synchronized(syncObj)
{
syncObj.wait();
}
}
catch(InterruptedException ie) { }
System.out.println("Main thread exiting...");
}
public void startBackgroundThread()
{
(new Thread(new Runnable()
{
#Override
public void run()
{
//Do something big...
System.out.println("Background Thread doing something big...");
//THEN HOW TO NOTIFY MAIN THREAD?
synchronized(syncObj)
{
System.out.println("Background Thread notifing...");
syncObj.notify();
}
System.out.println("Background Thread exiting...");
}
})).start();
}
}
and see this output
PS C:\Users\java> javac test.java
PS C:\Users\java> java test
Main thread waiting...
Background Thread doing something big...
Background Thread notifing...
Background Thread exiting...
Main thread exiting...
Just call notify()
public void run() {
try {
while ( true ) {
putMessage();
sleep( 1000 );
}
}
catch( InterruptedException e ) { }
}
private synchronized void putMessage() throws InterruptedException {
while ( messages.size() == MAXQUEUE )
wait();
messages.addElement( new java.util.Date().toString() );
notify();
}
You can't "notify the main thread".
The best approach is to use an ExecutorService, like this for example:
import java.util.concurrent.*;
// in main thread
ExecutorService executorService = Executors.newSingleThreadExecutor();
Future<?> future = executorService.submit(new Runnable() {
#Override
public void run() {
//Do something big...
}
});
future.get(); // blocks until the Runnable finishes
The classes are written specially to deal with asynchronous operations, and all the code in there is already written for you and bullet-proof.
Edit
If you don't want to block the main thread while waiting, wait within another thread:
final Future<?> future = executorService.submit(new Runnable() {
#Override
public void run() {
//Do something big...
}
});
new Thread(new Runnable() {
#Override
public void run() {
future.get(); // blocks until the other Runnable finishes
// Do something after the other runnable completes
}
}).start();
One thread notifying another thread is not a good way to do it. Its better to have 1 master thread that gives the slave thread work. The slave thread is always running and waits until it receives work. I recommend that you draw two columns and determine exactly where each thread needs to wait.
public void run()
{
//Do something big...
synchronized(this)
{
done = true;
}
}
Java includes libraries that make this really easy see ExecutorService and the following post
Producer/Consumer threads using a Queue