I'm working on a Java-based server in which I will have multiple threads (one thread for each connected user + some extra). There will be some database connection involved, so I was thinking that each time the server makes a SELECT query to the database it will start a new thread for this, to prevent blocking from the current thread. I'm planning on using a connection pool for this and I think I know how to do that. (I've looked into C3P0) However, there will be a lot of UPDATE statements involved also, but it's not important that these are ran directly, it's ok with a delay here. And since there might be a lot of UPDATE statements, I'm thinking of having a single worker thread for all UPDATE statements. As I see it, this will have the advantage of being able to re-use PreparedStatement-objects
The question:
How can I, from the other threads, tell the UPDATE-worker thread to run some statements? I know about multithreading and how to make threads "talk" to each other using synchronized blocks, but with the database involved it suddenly feels more complex. I have read that prepared statements and connections should not be shared between threads.
The idea I have right now on how to solve it: (doesn't feel like a good solution)
Use a LinkedBlockingQueue (or another kind of Queue) of a custom class with information about which kind of UPDATE statement to call and which parameters to send it. And then the worker thread will read from this queue when it's notified (which it will be when something is added to the queue) and there it will run the appropriate method which will use the appropriate prepared statement, set the params, and call it.
Edit: A bad think that I see myself with this approach is that the params might be ints, String, double, or whatever. How to store them in the custom class? Doesn't feel good to store them all as String.
Am I on the right track here or is there a better way to solve this?
No need for an explicit blocking queue. You can have a worker thread and a work queue encapsulated by an ExecutorService. As for the values, you can use generics:
class ThreadTask<T> implements Runnable {
private T value;
public ThreadTask(T value) {
this.value = value;
}
public void run() {
// update based on value
}
}
...
ExecutorService exec = Executors.newSingleThreadExecutor();
exec.submit(new ThreadTask<String>("asdf"));
exec.submit(new ThreadTask<Integer>(1));
The single thread executor is simply a worker thread waiting on a queue and executing the submitted tasks in order. No need for other explicit management.
Related
I have the following piece of code:
public static void main(String[] args) {
...
while(condition.continueListening()) {
}
log.info("Finished");
}
The condition object creates its own thread that after one condition is met, make the method continueListening, to return false.
The thing is that, I want the main thread to not to finish until that method returns false, and the way I implemented it, it's by using this structure that it's quite "hard" for the CPU, do you know any other approach that could work better?
What is continueListening checking? If its just a random piece of state, you don't really have a good choice, best you can do is make your thread sleep for a little bit, say a half second in the while loop.
But if you can change continueListening, then you can have it block until an event happens and it should continue. Java has many options for this, some could be:
You could wait for the other thread to exit using Thread.join().
Wait for the thread to notify on some object that it has done something (similar idea to join but the thread can carry on and do something else). Object.wait(), Object.notify().
Use the Java "executor", this is similar to waiting for a thread to exit, but has built in means to transfer results and errors, and allows Java to use things like thread pools. See ExecutorService and Future.get()
Various other waitable event objects or queues. Such as doing something manually with Future and Promise, or BlockingQueue.
Is there any way to put any sort of event listener that will be called when some thread - for example, the current thread - stops its activity and starts waiting or terminates?
I need this for the object to be notified and release some resources, when it is not in active use in this thread but still stored in memory somewhere that prevents it from being garbage collected - otherwise I'd place that resource releasing code in finalise() method.
UPD
Use case: an object that keeps a reference to a jdbc resultset or a database connection; the respective close() or commit() should be called automatically when the object is set aside temporarily or discarded at all without requiring the program to call any sort of cleanup method.
(There is no question how do I lock the object to be accessed from only one thread at a time, it is solved.)
The distinct non-answer: wrong design point. Threads don't "own" resources.
Threads are simply "threads of execution". They run the code you tell them to run. Therefore a thread doesn't own any of the objects it comes by.
As a consequence, there are no built-in mechanisms to help with your requirement. You would have to implement something yourself, relying on monitoring threads, and their states. Which would be a hard and challenging task. Mainly because: multi threading is hard.
The serious recommendation here: step back from this design. Rather think about other, different ways to deal with such "resources".
This is indeed a wrong approach.
You can obviously lock the object and unlock it in a finally block like this:
private Lock lock = new ReentrantLock();
public void useObject() {
lock.lock();
try {
//do something with your resource.
}
finally {
lock.unlock();
}
}
This way if the thread that runs useObject terminates, it will execute the finally block, and unlock the lock that protects the resource.
But there's NO way to detect the thread is not having any activity. If the thread is preempted by the Operation System, there's no way for you to know about it. That's below the abstraction level, you as a developer, operate.
If you want to gain more understanding on how the OS works with threads, and what you can cannot do you should check out
Java Multithreading, Concurrency & Performance Optimization
course on Udemy.
It also talks about how to properly use the right locks to do this kind of safe synchronization, and get the best performance from your application when you have to share resources such as database connections.
I hope it helps
and excuse the lack of knowledge on multithreaded apps, but I am new to the field.
Is there a pattern or common used methodology for monitoring the 'job completion' or 'job status' of worker threads from a monitor (a class that acts as a monitor)?
What I have currently done is create a list of workers and create one thread for each worker. After all threads have started i am looping over the worker list and 'checking their status' by making a call to a method.
At that time I couldn't come up with a different solution, but being new to the field, I don't know if this is the way to go, or if there are other solutions or patterns that I should study.
Depending on what you want, there are many ways that you can do this.
If you just want to wait until all the threads finish (i.e. all you care about is having everything finish before moving on), you can use Thread.join():
try {
for (Thread t: threadsIWaitOn)
t.join();
} catch (InterruptedException iex) {
/* ... handle error ...
}
If you want a more fine-grained control over the thread status and want to be able, at any time, to know what threads are doing, you can use the Thread.getState() function. This returns a Thread.State object that describes whether the thread is running, blocked, new, etc., and the Javadoc specifically says that it's designed for monitoring the state of a thread rather than trying to synchronize on it. This might be want you want to do.
If you want even more information than that - say, how to get a progress indicator for each thread that counts up from 0 to 100 as the thread progresses - then another option might be to create a Map from Threads to AtomicIntegers associating each thread with a counter, then pass the AtomicInteger into the constructor of each thread. That way, each thread can continuously increment the counters, and you can have another thread that continuously polls the progress.
In short, you have a lot of options based on what it is that you're trying to accomplish. Hopefully something in here helps out!
Use a ThreadPool and Executor, then you get a Future<> and you can poll for their completion and some more nice stuff, too. I can appreciate this book for you: Java Concurrency in Practice
Try to use any kind of synchronization. For example, wait on some kind of monitor/semaphore until job is done / whatever you need.
I suspect this is really easy but I’m unsure if there’s a naïve way of doing it in Java. Here’s my problem, I have two scripts for processing data and both have the same inputs/outputs except one is written for the single CPU and the other is for GPUs. The work comes from a queue server and I’m trying to write a program that sends the data to either the CPU or GPU script depending on which one is free.
I do not understand how to do this.
I know with executorservice I can specify how many threads I want to keep running but not sure how to balance between two different ones. I have 2 GPU’s and 8 CPU cores on the system and thought I could have threadexecutorservice keep 2 GPU and 8 CPU processes running but unsure how to balance between them since the GPU will be done a lot quicker than the CPU tasks.
Any suggestions on how to approach this? Should I create two queues and keep pooling them to see which one is less busy? or is there a way to just put all the work units(all the same) into one queue and have the GPU or CPU process take from the same queue as they are free?
UPDATE: just to clarify. the CPU/GPU programs are outside the scope of the program I'm making, they are simply scripts that I call via two different method. I guess the simplified version of what I'm asking is if two methods can take work from the same queue?
Can two methods take work from the same queue?
Yes, but you should use a BlockingQueue to save yourself some synchronization heartache.
Basically, one option would be to have a producer which places tasks into the queue via BlockingQueue.offer. Then design your CPU/GPU threads to call BlockingQueue.take and perform work on whatever they receive.
For example:
main (...) {
BlockingQueue<Task> queue = new LinkedBlockingQueue<>();
for (int i=0;i<CPUs;i++) {
new CPUThread(queue).start();
}
for (int i=0;i<GPUs;i++) {
new GPUThread(queue).start();
}
for (/*all data*/) {
queue.offer(task);
}
}
class CPUThread {
public void run() {
while(/*some condition*/) {
Task task = queue.take();
//do task work
}
}
}
//etc...
Obviously there is more than one way to do it, usually simplest is the best. I would suggest threadpools, one with 2 threads for CPU tasks, second with 8 threads will run GPU tasks. Your work unit manager can submit work to the pool that has idle threads at the moment (I would recommend synchronizing that block of code). Standard Java ThreadPoolExecutor has getActiveCount() method you can use for it, see
http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/ThreadPoolExecutor.html#getActiveCount().
Use Runnables like this:
CPUGPURunnable implements Runnable {
run() {
if ( Thread.currentThread() instance of CPUGPUThread) {
CPUGPUThread t = Thread.currentThread();
if ( t.isGPU())
runGPU();
else
runCPU();
}
}
}
CPUGPUThreads is a Thread subclass that knows if it runs in CPU or GPU mode, using a flag. Have a ThreadFactory for ThreadPoolExecutors that creates either a CPU of GPU thread. Set up a ThreadPoolExecutor with two workers. Make sure the Threadfactory creates a CPU and then a GPU thread instance.
I suppose you have two objects that represents two GPUs, with methods like boolean isFree() and void execute(Runnable). Then you should start 8 threads which in a loop take next job from the queue, put it in a free GPU, if any, otherwise execute the job itself.
I have a queue of tasks that need to be performed, and a pool of workers that pick up the tasks and perform them. There's also a "manager" class that keeps track of the worker, allows the user to stop or restart them, reports on their progress, etc. Each worker does something like this:
public void doWork() {
checkArguments();
performCalculation();
saveResultsToDatabase();
performAnotherCalculation();
saveResultsToDatabase();
performYetAnotherCalculation();
saveResultsToDatabase();
}
In this case, "database" does not necessarily refer to an Oracle database. That's certainly one of the options, but the results could also be saved on disk, in Amazon SimpleDB, etc.
So far, so good. However, sometimes the performCalculation() code locks up intermittently, due to a variety of factors, but mostly due to a poor implementation of networking code in a bunch of third-party libraries (f.ex. Socket.read() never returns). This is bad, obviously, because the task is now stuck forever, and the worker is now dead.
What I'd like to do is wrap that entire doWork() method in some sort of a timeout, and, if the timeout expires, give the task to someone else.
How can I do that, though ? Let's say the original worker is stuck in the "performCalculation()" method. I then give the task to some other worker, who completes it, and then the original worker decides to wake up and save its intermediate results to the database... thus corrupting perfectly valid data. Is there some general pattern I can use to avoid this ?
I can see a couple of solutions, but most of them will require some serious refactoring of all the business-logic code, from the ground up... which is probably the right thing to do philosophically, but is simply not something I have time for.
Have you tried using a Future? They are useful for running a task and waiting for it to complete, using a timeout etc. For example:
private Runnable performCalc = new Runnable() {
public void run() {
performCalculation();
}
}
public void doWork() {
try {
ExecutorService executor = Executors.newFixedThreadPool(1);
executor.submit(performCalc).get(); // Timeouts can be used here.
executor.submit(anotherCalc).get();
} catch(InterruptedException e) {
// Asked to stop. Rollback out transactions.
} catch(OtherExceptions here) {
}
}
If performCalculation stuck on blocking IO, there is little you can do to interrupt it. One solution is to close the underlying socket or set timeout on socket operations using Socket.setSoTimeout, but you have to own the code which reads from the socket to do that.
Otherwise you can add some reconciliation mechanism before saving the data into the database. Use some kind of timestamps to detect if the data in the database is newer that the data which original worker fetched from the network.
I suppose the easiest thing to do would be to have a separate timer thread, started when the thread with performCalculation() starts. The timer thread can wake up after a period of time and Thread.interrupt() the calculation thread, which can then perform any necessary rollback when handling the InterruptedException.
Granted, this is bolting on additional complexity to manage other problems, and consequently isn't the most elegant solution.