I have an application with a main class that sets up a thread executor for a few other runnable classes however I want an update method in the main class to be called regularly also so is it best to create a thread like in the example below OR submit the class to the thread executor declared inside it (something like in the example below the example)?
Feels wrong using a mixture of thread executors and starting standard threads.
Use standard thread call for main classes updates?
public class Test {
private ScheduledExecutorService scheduledThreadPool; //used for creating other threads
private Thread t;
public Test() {
t = new Thread() {
#Override
public void run() {
try {
while (true) {
processUpdates();
Thread.sleep(10);
}
} catch (InterruptedException e) {
logger.error(e);
}
}
};
}
private void processUpdates() {
//do some stuff
}
}
OR use thread executor for not just the other runnable classes but the main class itself?
public class Test implements runnable {
ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(3);
public Test() {
scheduledThreadPool.scheduleWithFixedDelay(this, 0, 10, TimeUnit.MILLISECONDS);
}
# Override
public void run() {
processUpdates();
}
private void processUpdates() {
//do some stuff
}
}
Thanks!
Always use thread pools over plain old threads: it gives you much more control over the execution of your threads.
If you want all your threads to run in parallel, you can always use an unlimited thread pool, which is discouraged because Thread is costly in memory.
In your case, the use of a ScheduledExecutorService is even more recommended since it avoids the sleep instruction in your thread implementation. It gives better performance and a much better readability.
Related
Threads add a lot of verbal to the code and make it harder to understand and reason about. Look at this code for example:
public class ConnectionListener implements Runnable {
private Thread thread;
private boolean running;
public void start() {
if (!running) {
thread = new Thread(this);
thread.start();
}
}
public void stop() {
if (running) {
running = false;
thread.interrupt();
}
}
#Override
public void run() {
running = true;
while (running) {
// Do some crap
}
}
}
The whole concern of this class should be listening for connection requests from the network. But look how many lines of code are added just for managing a thread. Is there any way to make this code cleaner?! I don't want to see the thread = new Thread();, not the thread variable and not any of the stop()/start() methods!
Of course I know what the ExecutorService is... But what if I want to manage a long-running thread? By long-running thread, I mean a thread with a life cycle long as the application's life cycle.
Do you have any good solution for me? A way to remove the thread creation and management concerns from a class without making the class extend another class?
I solved the problem by using a single-threaded executor service. I've also read about the performance differences between Plain Thread, ThreadPool and SingleThreadExecutor - SingleThreadExecutor VS plain thread.
Using a single thread executor allows me to start a single thread and manage it using its Future. See code example:
public void func(String[] args) {
ExecutorService es = Executors.newSingleThreadExecutor();
Future<?> f = es.submit(Some Runnable);
}
Thanks to #BasilBourque that gave me this solution in the comments.
I am working on a module where a one-time cache is loaded using the static workflow. Cache loading usually takes around an hour. To improve the performance I am thinking about running these tasks in parallel using a thread pool. Here is the sample code.
Application Startup class:
public class AppStart {
public static void main(String[] args) {
Cache.isValid(); // this will trigger the static workflow
// ...
}
}
Cache loader class:
public class Cache {
static {
System.out.println("Static block initialization started!");
initialize();
System.out.println("Static block initialization finished!");
}
public static void initialize( ) {
System.out.println("initialize() started!");
ExecutorService executorService = Executors.newSingleThreadExecutor(); // will replace with fixedThreadPool
Future<String> future = executorService.submit(() -> "Hello world!");
System.out.println("Retrieve the result of the future");
String result = null;
try {
result = future.get();
System.out.println(result);
} catch( InterruptedException e ) {
e.printStackTrace();
} catch( ExecutionException e ) {
e.printStackTrace();
}
executorService.shutdown();
}
public static boolean isValid( ) {
return true;
}
}
However, in the above case blocking operation future.get is getting blocked forever, even though it does nothing but a trivial task to return a String.
I also tried using ForkJoinPool, I had no luck.
I monitored threads using jconsole could not detect any deadlock. why is it behaving weirdly?
The static initializer for your Cache class doesn't complete – it's waiting on the completion of future.get(). You could remove the static initializer and call your method directly – Cache.initialize() – from main() or somewhere else, but whatever thread does that is going to be similarly blocked.
I suggest you create a separate thread to call initialize(), thus avoiding the blocking behavior, like this:
new Runnable() {
#Override
public void run() {
initialize();
}
}.run();
This seems to be the expected behavior. this is a classic class initialization deadlock.
a new Thread is started using the Runnable that is dependent on the completion of static initialization of a class. The class is, in turn, waiting for the Runnable to finish because of the future.get() method call.
The static initialization is waiting for thread to complete and thread is waiting for static initialization to complete.
JLS:: Class initialiization gives details on the class initialization process.
I wonder why jconsole couldn't detect the deadlock
I am using ThreadPoolExecutor for pooling threads. Everytime I want to do an IO operation like writing results to a file I make use of the submit method to execute a runnable. Below is the code I have written:
**ThreadPool class looks like this:**
private static ThreadPoolExecutor executors = new ThreadPoolExecutor(8, 16, 25, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(2));;
public static void dispose(){
// end all running queues and destroy this object
executors.shutdown();
executors.shutdownNow();
}
public static void submit(Runnable r){
executors.submit(r);
}
Here is where I am submitting a runnable task to the thread pool
ThreadPool.submit(new Runnable() {
Output streamOutput = new Output(outputFileHandle.write(true));
#Override
public void run() {
if(Thread.interrupted()){
streamOutput.close();
}
writeToFile(streamOutput);
}
});
This is what happens inside WriteFile:
protected void WriteToFile(Output streamOutput){
try{
// Write to file which can take lots of time
}catch(Exception e){
// print e stack trace
}finally{
streamOutput.close();
}
}
Some threads I looked at suggested that shutdownNow() doesn't gaurantee stopping of the tasks; instead they just call .interrupt(). How should I make my Runnable handle an interrupt while its in the middle of writing to a file. Nevertheless, my objective is "to gaurantee that the stremOutput resource is closed everytime"
How should I achieve this?
My application has 1 global driver, which is responsible for doing the low-level work.
I then have 2 threads, both of which use infinite loops to get some work done. My question is how to allow 1 thread to use the driver as much as possible, but giving a chance to the second thread to use it when necessary.
To elaborate, the code I have is as follows:
public class Game {
private static final Object LOCK = new Object();
private static final Logger LOGGER = Logger.getLogger(Game.class);
private WebDriverController controller;
public Game(WebDriverController controler) {
this.controller = controller;
}
public void startThreadA() {
new Thread(new Runnable() {
#Override
public void run() {
while (true) {
synchronized (LOCK) {
controller.doSomethingA();
}
}
}
}).start();
}
public void startThreadB() {
new Thread(new Runnable() {
#Override
public void run() {
while (true) {
...
...
synchronized (LOCK) {
controller.doSomethingB();
}
...
...
}
}
}).start();
}
}
The logic is to allow the first thread to execute doSomethingA() as much as possible, with the second thread only acquiring the lock to complete little tasks and then giving the lock back to the first thread.
Using this code, the first thread will continuously use the controller to do what it needs to do, whereas the second thread gets stuck waiting at its synchronized block. The way I have currently fixed this is by adding a pause to the first thread, to give the second thread a chance to acquire the lock, as follows:
public void startThreadA() {
new Thread(new Runnable() {
#Override
public void run() {
while (true) {
synchronized (LOCK) {
controller.doSomethingA();
}
try {
Thread.sleep(1);
} catch (InterruptedException e) {
LOGGER.error(null, e);
}
}
}
}).start();
}
This does work exactly as intended, but it doesn't seem right. I'm not happy with the manual pause after each iteration, especially if the second thread does not need the lock as it's wasting time.
What do I replace the pause with to make this more efficient?
Why you use synchronized in run()? Use synchronized or Lock in your methods in WebDriverController.
public void doSomeThingA(){
lock.lock();
try {
//your stuff
} finally {
lock.unlock();
}
}
And in run method of Thread invoke these methods.
I think you are approaching this from the wrong direction, as in your current setup 99.999% of the time thread A calls for a monitor the processing time is wasted. However as I do not have enough details about your actual problem, here is a quick solution using a ReentrantLock with fair scheduling (FIFO):
protected final ReentrantLock lock = new ReentrantLock(true); // fair scheduling
public void functionA() {
lock.lock();
try {
controller.functionA();
} finally {
lock.unlock();
}
}
public void functionB() {
lock.lock();
try {
controller.functionB();
} finally {
lock.unlock();
}
}
Explanation:
If Thread A is currently holding the lock and Thread B calls, B is guaranteed to receive the monitor right after A releases it, even if A immediately (before any thread switch occurs) calls for it again.
There are a few options here. The best bet in this instance is likely to be remove the responsibility of deciding when to do work from the threads and instead, waiting for an event from a monitor to release the threads to do work. You can then schedule the work in whichever ratio is best suited to the purpose.
Alternatively, remove the lack of thread safety from your controller code.
Assuming that above thread organization is the best way to go for your particular case, your problem is that first thread holds the lock too long, thus starving the second one.
You can check if doSomethingA function really needs locked driver all the time while it is being executed (in most cases it doesn't), and if not split it into multiple smaller execution blocks, some of which hold the lock while other's don't. This will create more time for second thread to kick in when it needs to.
If that cannot be done then you really need to rethink your app, because you have created a resource bottleneck.
It looks like Thread.yield () is what you are looking for.
As far as my understanding is so far; a class which implements runnable seems to only be able to perform one set task within its run method. How is it possible to create a new thread and then run different methods from this one additional thread, without needing to create some new runnable class for every set task.
Make your own subclass of Thread (MyThread extends Thread)
Add private members to control the behavior.
Add bean-pattern get/set methods to control the private members, or use a fluent API.
Read this properties in the run() method.
MyThread t = new MyThread();
t.setTypeOfSparrow("African");
t.setFavoriteColor("Yellow");
t.start();
Your Runnable class can call any logic it likes. The logic you want to run must be in some class, could be different methods of the Runnable class or could be in lots of other classes.
How did you plan to tell the runnable what to do?
You could do something like:
MyRunnable implements Runnable {
private String m_whatToDo;
public MyRunnable(String whatToDo) {
m_whatToDo = whatToDo;
}
public void Runnable run() {
if ("x".equals(m_whatToDo) {
// code to do X
} else if ( "y".equals(m_whatToDo) {
// code to do Y
} else {
// some error handling
}
}
}
Or as Srikanth says you could communicate the intent by other means such as thread names.
However I don't see much overhead in creating a runnable class. Just adding a public void run() to a class is surely not that big a deal?
A class should perform one task and perform it well, and if you are adding multiple operations in a single Runnable then you are violating this principle. You should create a new implementation of Runnable for each runnable task.
To simplify your api you might like to create a MyRunnableFactory method which constructs a runnable class depending on one or more construction criteria. This would shield the user from having to remember which class to create for each task.
Your question isn't quite clear. My guess is that you want to run different methods in some other thread, but you don't want to waste time restarting a new thread for each method. In that case you need an ExecutorService with one thread. You can submit sequentially some Runnables to a thread that is kept alive between calls.
Or more simply if you already know the order in which your methods are called
(new Thread() {
#Override public void run() {
method1();
method2();
...
}
}).start();
In the run() method check for the thread name and call the appropriate method.
public class SampleThread implements Runnable{
/**
* #param args
*/
Thread t=null;
public SampleThread(String threadName)
{
t=new Thread(this,threadName);
t.start();
}
#Override
public void run() {
if(t.getName().equals("one"))
{
One();
}
else if(t.getName().equals("two"))
{
Two();
}
}
public void One()
{
System.out.println(" ---- One ---- ");
}
public void Two()
{
System.out.println(" ---- Two ---- ");
}
public static void main(String[] args) {
SampleThread t1=new SampleThread("one");
SampleThread t2=new SampleThread("two");
}
}