First time I am working with threads in spring boot webapp and when I do debugging then I see thread names are increasing like Thread-1, Thread-2... for every call method so I thought that the program is not killing the thread but creating new thread for every call.
Here is my code:
public Advert saveAdvert(Advert advert) {
Advert advertToSave = advertRepository.save(advert);
new Thread(() -> {
try {
populateAdvertSearch(advertToSave);
} catch (ParseException e) {
e.printStackTrace();
} catch (OfficeNotFoundException e) {
e.printStackTrace();
} catch (OfficePropertyNotFoundException e) {
e.printStackTrace();
}
}).start();
return advertToSave;
}
Here populateAdvertSearch() is a void method. I just want to do that task independently from the main thread because it is very long and I do not want client to wait whole method so another independent thread will do this void method. But as I said I though that the program is not killing threads. How can I kill the thread or Should I kill explicitly (I am not sure maybe it is already killed after execution is done but then why Intellij IDEA debug showing thread names as increasing)
After thread starts and run() method returns, that Thread will terminate and eventually be garbage collected. You see incrementing id numbers because you are starting new threads for each such action. So no explicit termination is required.
Use #Async
In a Web Application, creating Threads manually isn't the right way to go. This process is constful, and it's better to maintain a Pool of Threads.
Since you're using Spring Boot, everything you need is annotate the configuration class with #EnableAsync and ThreadPoolTaskExecutor would be configured for you under the hood. You can customize it via application.properties (for instance, specify the required min/max pool size).
And to tell that a certain method should be executed in a different Thread, you need to place annotation #Async on it (note that this method should reside in a class managed by Spring, i.e. annotated with one of the stereotype annotations #Component, #Controller, etc.).
#Async
public Advert saveAdvert(Advert advert) {
Advert advertToSave = advertRepository.save(advert);
try {
populateAdvertSearch(advertToSave);
} catch (ParseException e) {
e.printStackTrace();
} catch (OfficeNotFoundException e) {
e.printStackTrace();
} catch (OfficePropertyNotFoundException e) {
e.printStackTrace();
}
return advertToSave;
}
Well, it's not a good idea to terminate a running thread from the outside, but if you want so, you can use ExecutorService.
Let's say you want to kill specific thread after 5 seconds;
if (executor.awaitTermination(5, TimeUnit.SECONDS)) {
// continue
} else {
// force shutdown
executor.shutdownNow();
}
Related
In my Spring application, there is a scheduler for executing some task. Scheduled annotation is not used there because the schedule is quite complicated - it is dynamic and it used some data from the database. So simple endless cycle with thread sleeping is used. And sleeping interval is changed according to some rules. Maybe all this can be done with Scheduled annotation, but the question is not about that.
Below is simple example:
#Service
public class SomeService {
#PostConstruct
void init() {
new Thread(() -> {
while (true) {
System.out.println(new Date());
try {
Thread.sleep(1000);
} catch (Exception ex) {
System.out.println("end");
return;
}
}
}).start();
}
}
The code works fine but there is some trouble with killing that new thread. When I stop the application from Tomcat this new thread is continuing to run. So on Tomcat manage page I see that application is stopped, but in Tomcat log files I still see the output from the thread.
So what the problem? How I should change the code so the thread would be killed when the application is stopped?
Have you tried to implement a #PreDestroy method which will be invoked before WebApplicationContext is closed to change a boolean flag used in your loop? Though it seems strange that your objects are not discarded even when application is stopped...
class Scheduler {
private AtomicBoolean booleanFlag = new AtomicBoolean(true);
#PostConstruct
private void init() {
new Thread(() -> {
while (booleanFlag.get()) {
// do whatever you want
}
}).start();
}
#PreDestroy
private void destroy() {
booleanFlag.set(false);
}
}
I am currently working on a MMORPG game and have a FixedThreadPool which contains 4-8(depending on hardware) runnable objects which handle the movements in game.
Here is the run method of the Runnable.
#Override
public void run() {
while(serverRunning){
synchronized (movementQueue) {
movementQueue.stream()
.parallel()
.filter((player) -> player != null && player.hasMovement())
.forEach((player) -> player.move());
}
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
These runnable will run as long as the server is running. Now there are many places I read that ThreadPools should only be used when the tasks are no longer than few seconds, but nowhere they explain what is the reason behind it.
If so what is the reason? I am new to java and trying to learn better ways to do a solution hence let me know if there is any other better way to do it.
tyrus websockets ClientManager connectToServer 'Handshake response not received'
how do I retry the connection without more and more daemon and Grizzly-kernel and Grizzly-worker threads created.
Is there a call to Session or client to kill/cleanup
Thread-1 to 4 and Grizzly-kernel and Grizzly-worker threads?
Example JAVA main line which attempts forever to make and maintain a connection with a server which may not be running or is periodically restart.
public void onClose(Session session, CloseReason closeReason) {
latch.countDown();
}
enter code here
public static void main(String[] args) {
while (true) {
latch = new CountDownLatch(1);
ClientManager client = ClientManager.createClient();
try {
client.connectToServer(wsListener.class, new URI("wss://<host>/ws"));
latch.await();
}
catch (DeploymentException e) {
try {
Thread.sleep(1000);
} catch (InterruptedException ie) {
break;
}
}
catch (Exception e) {
throw new RuntimeException(e);
}
client = null;
latch = null;
// HERE... clean up
}
}
client.connectToServer returns Session instance and when you call Session.close(), client runtime should be shut down (no threads left).
You did not specify version of Tyrus you are using (I recommend 1.3.3, we made some improvements in this area). Also you might be interested in our shared container support, see TYRUS-275. You could combine it with Thread pool config and you should have much better control of number of spawned/running threads.
We are always looking for new use cases, so if you think you have something which should be better supported in Tyrus, feel free to create new enhancement request on our JIRA.
I got this exact same behavior. I was using a lot of threads and synchronization and managed to accidently get the onOpen method of the ClientEndpoint blocking which caused the handshake to time out.
I'm currently attempting to write a Logger style thread. I'm not using the existing API because this is partially an exercise to improve my threading.
When the thread is interrupted, I need it to shutdown gracefully, flushing the last of it's queued messages and closing the file streams.
Currently, it shuts down but messages are often still in queue, and I'm concerned that the file streams aren't being closed gracefully.
This is my run()
while(!shutdown){
writeMessages();
try{
Thread.sleep(5000);
}
catch (InterruptedException e) {
}
}try {
writeMessages();
} catch (CustomException e1) {
e1.printStackTrace();
}
try {
logFile.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
errFile.close();
} catch (IOException e) {
e.printStackTrace();
}
Java has very neat way to shutdown threads. It's called interruption flag. When you want to interrupt thread you simply write following code:
thread.interrupt();
thread.join();
And in the Runnable of background thread you should check interruption flag and behave accordingly. If you want thread to survive until messages are left you can do it in a following manner (I assume you have some way of checking is there any messages left. In my case it's a BlockingQueue):
Thread self = Thread.currentThread();
BlockingQueue<String> messages = ...;
while (!self.isInterrupted() || !messages.isEmpty()) {
try {
String message = messages.take();
writeMessage(message);
} catch (InterruptedException) {
self.interrupt();
}
}
One more thing. You should ensure that messages are not added to the queue after thread shutdown is requested or shutdown all threads generating messages before writing thread. This also could be done checking thread interruption flag (you need to know reference to a writer thread):
public void addMessage(String message) {
if (thread.isInterrupted() || !thread.isAlive()) {
throw new IllegalStateException();
}
messages.add(message);
}
Also I recommends you to see at java.util.concurrent package. It have a lot of useful tools for multithreaded applications.
Use the finally block to add your flushing instructions.
All other comments are good, I just want to add - make sure that you called flush() on your output streams before closing them.
I have a service which process a request from a user.
And this service call another external back-end system(web services). but I need to execute those back-end web services in parallel. How would you do that? What is the best approach?
thanks in advance
-----edit
Back-end system can run requests in parallel, we use containers like (tomcat for development) and websphere finally for production.
So I'm already in one thread(servlet) and need to spawn two tasks and possibly run them in parallel as close together as possible.
I can imagine using either quartz or thread with executors or let it be on Servlet engine. What is proper path to take in such a scenario?
You can use Threads to run the requests in parallel.
Depending on what you want to do, it may make sense to build on some existing technology like Servlets, that do the threading for you
The answer is to run the tasks in separate threads.
For something like this, I think you should be using a ThreadPoolExecutor with a bounded pool size rather than creating threads yourself.
The code would look something like this. (Please note that this is only a sketch. Check the javadocs for details, info on what the numbers mean, etc.)
// Create the executor ... this needs to be shared by the servlet threads.
Executor exec = new ThreadPoolExecutor(1, 10, 120, TimeUnit.SECONDS,
new ArrayBlockingQueue(100), ThreadPoolExecutor.CallerRunsPolicy);
// Prepare first task
final ArgType someArg = ...
FutureTask<ResultType> task = new FutureTask<ResultType>(
new Callable<ResultType>() {
public ResultType call() {
// Call remote service using information in 'someArg'
return someResult;
}
});
exec.execute(task);
// Repeat above for second task
...
exec.execute(task2);
// Wait for results
ResultType res = task.get(30, TimeUnit.SECONDS);
ResultType res2 = task2.get(30, TimeUnit.SECONDS);
The above does not attempt to handle exceptions, and you need to do something more sophisticated with the timeouts; e.g. keeping track of the overall request time and cancelling tasks if we run over time.
This is not a problem that Quartz is designed to solve. Quartz is a job scheduling system. You just have some tasks that you need to be executed ASAP ... possibility with the facility to cancel them.
Heiko is right that you can use Threads. Threads are complex beasts, and need to be treated with care. The best solution is to use a standard library, such as java.util.concurrent. This will be a more robust way of managing parallel operations. There are performance benefits which coming with this approach, such as thread pooling. If you can use such a solution, this would be the recommended way.
If you want to do it yourself, here is a very simple way of executing a number of threads in parallel, but probably not very robust. You'll need to cope better with timeouts and destruction of threads, etc.
public class Threads {
public class Task implements Runnable {
private Object result;
private String id;
public Task(String id) {
this.id = id;
}
public Object getResult() {
return result;
}
public void run() {
System.out.println("run id=" + id);
try {
// call web service
Thread.sleep(10000);
result = id + " more";
} catch (InterruptedException e) {
// TODO do something with the error
throw new RuntimeException("caught InterruptedException", e);
}
}
}
public void runInParallel(Runnable runnable1, Runnable runnable2) {
try {
Thread t1 = new Thread(runnable1);
Thread t2 = new Thread(runnable2);
t1.start();
t2.start();
t1.join(30000);
t2.join(30000);
} catch (InterruptedException e) {
// TODO do something nice with exception
throw new RuntimeException("caught InterruptedException", e);
}
}
public void foo() {
Task task1 = new Task("1");
Task task2 = new Task("2");
runInParallel(task1, task2);
System.out.println("task1 = " + task1.getResult());
System.out.println("task2 = " + task2.getResult());
}
}