ConditionVariable prevents both threads from running simultaneously - java

I am trying to enforce synchronization between a pair of Android threads for game programming purposes. I have assigned a game thread, which handles most duties, and a render thread, which is tasked with swapping buffers and rendering. When I first asked about thread synchronization, I was referred to the ConditionVariable object as a useful tool to force threads to block until concurrent tasks are completed.
My source code looks like this:
...
final ConditionVariable bufferLock = new ConditionVariable();
final ConditionVariable cycleLock = new ConditionVariable();
bufferLock.open();
cycleLock.open();
Runnable bufferSwapTask = new Runnable()
{
public void run()
{
swapBuffers();
bufferLock.open();
}
};
Runnable renderTask = new Runnable()
{
public void run()
{
Log.d(TAG, "drawAll");
drawAll();
cycleLock.open();
}
};
while(!halt)
{
if(!init)
{
synchronized (userInputLock)
{
fetchUserInput();
}
processUserInput();
gameLogic();
bufferLock.block();
cycleLock.close();
renderThreadHandler.post(renderTask);
recycleDisplayObjects();
enqueueDisplayTree();
cycleLock.block();
bufferLock.close();
renderThreadHandler.post(bufferSwapTask);
}
}
...
So things executed in the right order, but not with the level of performance I had expected. And, when I activated DDMS method tracing, I found that the DVM would actually interrupt and block each thread to allow the other thread to resume, switching back and forth in a manner that strongly suggests that both threads are only being processed by one CPU.
I have had nice simultaneous processing results using ReentrantLocks, so why does ConditionVariable have this effect?

The Linux kernel on Android tries to avoid moving threads between cores. If a thread is "runnable" (i.e. could run but is waiting on another thread) for a while, the kernel can decide to migrate it to another core.
If, in the previous implementation, one of your threads tended to run continuously, it may have kept the other thread in "runnable" long enough to cause the kernel to migrate it. The new implementation might be moving in smaller steps and fall below the threshold.
FWIW, other people have been puzzled by this, e.g. here and here.

Related

Java multi-threading execution on CPU core

Context
Let's say I have a simple Java multi threading program with
class Runner1 implements Runnable {
#Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("Runner1: " + i);
}
}
}
class Runner2 implements Runnable {
#Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("Runner2: " + i);
}
}
}
public class App {
public static void main(String[] args) {
Thread t1 = new Thread(new Runner1());
Thread t2 = new Thread(new Runner2());
t1.start();
t2.start();
}
}
The program is running on a multiple core laptop e.g. 4 cores. My understanding from related post is that multithreading can be executed on a single core.
Question
I was wondering about the behavior of the JAVA 2 threads execution on the cpu.
Will the 2 threads be executed by a single cpu core or will they be allocated to different cpu core for execution? Is there a mechanism or default scenario to decide the allocation?
Thanks!
Each thread has an execution stack that tracks its state. It does not matter whether the two threads run on the same CPU or different CPU. In fact what usually happens is that a thread runs a little bit at a time, and the same CPU can be switch back and forth, running one thread for a while, and running the other for a while.
When the threads are allocated to different CPUs, then the possibility of conflicting updates to shared objects is greater, because the threads could be running at the same time causing fine-grained interweaving of updates to memory. If you design your threads to protect against concurrency problems, then it really does not matter much whether they run on the same CPU or different CPU. It does not matter if the thread is run sometimes on one CPU, and later by a different CPU. The thread holds all its own state and does not matter which CPU runs it.
It seems that Java delegates to the operating system the decision on where to run a particular thread.
It can be run on a single-core, but care must be taken when one thread is doing read and the other one does write operation. Internal workings are taken care of by the OS (scheduler).
There is not much to add to the answer of AgilePro.
If you want to control which CPU runs which threads, you need to pin down the thread to a CPU. You could use Thread Affinity library of Peter Lawrey when using Java.
On Linux, every thread has a bitmap with a single bit per CPU the thread is allowed to run on. By default, all bits are set, meaning the thread can run on any CPU. And thread can even migrate from one CPU to another. But using certain system calls, one can pin down a thread to a subset (even a single) of CPUs.

Drawbacks to an idling fixed threadpool

I'm currently in the process of doing various performance improvements in a software. As it is using SWT for it's GUI, I have come across a problem where under certain circumstances a lot of UI elements are created in the Display Thread.
Since the person before me, didn't really take care to do any calculations outside of the Display Thread, the whole software can be unresponsive for several seconds on startup.
I've now isolated the code that needs to be performed in the Display Thread, and I'm now calculating everything else in Runnables that I submit to a fixed Threadpool.
I'm using the pool like this:
public abstract class AbstractChartComposite {
private static ExecutorService pool = Executors.newFixedThreadPool(8);
private List<String> currentlyProcessingChartItems = new ArrayList<>();
protected void doCalculate(constraints){
for (IMERuntimeConstraint c : constraints) {
if(!currentlyProcessingChartItems.contains(c.getId())){
currentlyProcessingChartItems.add(c.getId());
pool.submit(new Runnable(){
#Override
public void run() {
try{
createChartItem(c);
currentlyProcessingChartItems.remove(c.getId());
}catch(Throwable e){
e.printStackTrace();
}
}
});
}
}
}
}
I'm now wondering, if I have any drawbacks to leaving the Threadpool running at idle, once all the UI elements have been created. I cannot really shut it down for garbage collection, because it will be needed again on user Input when a new element needs to be created.
So are there any major drawbacks on leaving a threadpool with no submitted Runnables running?
No, there are no drawbacks.
The threads won't be actually running, they'll be parked until a new task is submitted. So it does not affect CPU. Also you say that you will use this pool again, so in your case there's no point of shutting it down and recreating again.
As to the memory - yes, idle threads will consume some amount of memory, but that's not an issue as well, until you have hundreds (thousands?) of threads.
Also, a piece of advice. Do not do premature optimizations. That's the root of all evil. Analyze a problem once you have real performance issues, using special utilities for that and detecting bottlenecks.

Having threads run from event listeners in java?

I have a program that creates hundreds of instances of a class, each of which listens to another thread which simply fires an event on a regular timed schedule (so that they all perform at the same speed). What I'd like is for each of the hundreds of instances to be its own thread, so that when an event is fired, they can all work in parallel. What makes sense to me is to have these classes extend the Thread class and then have this code inside them...
public class IteratorStepListener implements StepEventListener {
public void actionPerformed(ActionEvent e) {
start();
}
}
public void run() {
doStuff();
}
This doesn't seem to work though. Clearly I'm not understanding something basic here. What's the proper way to do this?
Okay, first thing: overcome the notion that your hundreds of threads will run in parallel. At the very best, they will run concurrently, ie, time-sliced. As you get into the hundreds of threads, you will see the bearings on the scheduling algorithm start to glow; in the thousands they'll smoke and eventually seize up, and you'll get no more threads.
Now, that said, we don't have near enough code to understand what you're really doing, but one thing that I note is you don't seem to be making new Threads. Remember that a thread is an object; the canonical way to start a thread is
Thread t = new Thread(Runnable r);
t.run();
What it looks like is that you're trying to run() the same thread over and over again; this way lies madness. Have a look at Wiki on Event Driven Programming. If you really want to have a separate thread for handling each event, you'll want a scheme something like this (pseudocode):
processEvents: function
eventQueue: queue of Events
event: implements Runnable
-- something produces events and puts them on the queue
loop -- forever
do
Event ev := eventQueue.front
new Thread(ev).run();
od
end -- processEvents
It sounds like the event is going to be fired more than once... but you can't start the same thread more than once.
It sounds like your listener should implement the interface but start a thread directly in actionPerformed (or better, use an Executor so that it could use a thread pool). So instead of your current implementation, you could use:
// Assuming the listener implements runnable; you may want to
// delegate that to a separate class for separation of concerns.
public void actionPerformed(ActionEvent e) {
new Thread(this).start();
}
or
public void actionPerformed(ActionEvent e) {
executor.execute(this);
}
What I'd like is for each of the hundreds of instances to be its own thread, so that when an event is fired, they can all work in parallel.
I don't think this is a good approach.
Unless you have hundreds of processors, the threads cannot possibly all work in parallel. You'll end up with the threads running them one at a time (one per processor), or time-slicing between processors.
Each thread actually ties down a significant slice of the JVM's resources, even when inactive. IIRC, the default stack size is about 1 Mbyte.
The example code in your question shows the event calling start() on the thread. Unfortunately, you can only call start() on a thread once. Once the thread has terminated it cannot be restarted.
A better approach would be to create an executor with a bounded thread pool, and have each event cause a new task to be submitted to the executor. Something like this:
ThreadPoolExecutor executor = new ThreadPoolExecutor(corePoolSize, maxPoolSize,
keepAliveTime, timeUnit, workQueue);
...
public class IteratorStepListener implements StepEventListener, Runnable {
public void actionPerformed(ActionEvent e) {
executor.submit(this);
}
public void run() {
doStuff();
}
}
You can't use threads like that in Java. This is because Java threads directly map to underlying OS threads (at least on JVM implementations that I'm aware of), and OS threads can't scale like that. A rule of thumb is, you want to keep total number of threads within hundred or something in an app. A few hundred is probably ok. A few thousand gets usually problematic, depending on the HW you are using.
The use of threads like you described is a valid implementation strategy in languages like Erlang for example. Meanwhile, if you are stuck with Java this time, creating a shared thread pool and submitting your tasks to this instead of allowing all tasks to run concurrently might be a good alternative. In this case, you can choose a suitable number of threads (best number depends on the nature of the task. If you have no idea, number of CPU core available times 2 is a good start), and have that number of tasks run concurrently.
If you absolutely need all tasks to proceed concurrently, it could get a little complicated, but that's doable as well.

Why can't a Java Thread object be restarted?

I know that it is not possible to restart a used Java Thread object, but I don't find an explanation why this is not allowed; even if it is guaranteed that the thread has finished (see example code below).
I don't see why start() (or at least a restart()) method should not be able to somehow reset the internal states - whatever they are - of a Thread object to the same values they have when the Thread object is freshly created.
Example code:
class ThreadExample {
public static void main(String[] args){
Thread myThread = new Thread(){
public void run() {
for(int i=0; i<3; i++) {
try{ sleep(100); }catch(InterruptedException ie){}
System.out.print(i+", ");
}
System.out.println("done.");
}
};
myThread.start();
try{ Thread.sleep(500); }catch(InterruptedException ie){}
System.out.println("Now myThread.run() should be done.");
myThread.start(); // <-- causes java.lang.IllegalThreadStateException
} // main
} // class
I know that it is not possible to
restart a used Java Thread object, but
I don't find an explanation why this
is not allowed; even if it is
guaranteed that the thread has
finished (see example code below).
My guestimation is that Threads might be directly tied (for efficiency or other constrains) to actual native resources that might be re-startable in some operating systems, but not in others. If the designers of the Java language had allowed Threads to be re-started, they might limit the number of operating systems on which the JVM can run.
Come to think of it, I cannot think of a OS that allows a thread or process to be restarted once it is finished or terminated. When a process completes, it dies. You want another one, you restart it. You never resurrect it.
Beyond the issues of efficiency and limitations imposed by the underlying OS, there is the issue of analysis and reasoning. You can reason about concurrency when things are either immutable or have a discrete, finite life-time. Just like state machines, they have to have a terminal state. Is it started, waiting, finished? Things like that cannot be easily reasoned about if you allow Threads to resurrect.
You also have to consider the implications of resurrecting a thread. Recreate its stack, its state, is is safe to resurrect? Can you resurrect a thread that ended abnormally? Etc.
Too hairy, too complex. All that for insignificant gains. Better to keep Threads as non-resurrectable resources.
I'd pose the question the other way round - why should a Thread object be restartable?
It's arguably much easier to reason about (and probably implement) a Thread that simply executes its given task exactly once and is then permanently finished. To restart threads would require a more complex view on what state a program was in at a given time.
So unless you can come up with a specific reason why restarting a given Thread is a better option than just creating a new one with the same Runnable, I'd posit that the design decision is for the better.
(This is broadly similar to an argument about mutable vs final variables - I find the final "variables" much easier to reason about and would much rather create multiple new constant variables rather than reuse existing ones.)
Because they didn't design it that way. From a clarity standpoint, that makes sense to me. A Thread represents a thread of execution, not a task. When that thread of execution has completed, it has done its work and it just muddies things were it to start at the top again.
A Runnable on the other hand represents a task, and can be submitted to many Threads as many times as you like.
Why don't you want to create a new Thread? If you're concerned about the overhead of creating your MyThread object, make it a Runnable and run it with a new Thread(myThread).start();
Java Threads follow a lifecycle based on the State Diagram below. Once the thread is in a final state, it is over. That is simply the design.
You can kind of get around this, either by using a java.util.concurrent.ThreadPoolExecutor, or manually by having a thread that calls Runnable.run() on each Runnable that it is given, not actually exiting when it is finished.
It's not exactly what you were asking about, but if you are worried about thread construction time then it can help solve that problem. Here's some example code for the manual method:
public class ReusableThread extends Thread {
private Queue<Runnable> runnables = new LinkedList<Runnable>();
private boolean running;
public void run() {
running = true;
while (running) {
Runnable r;
try {
synchronized (runnables) {
while (runnables.isEmpty()) runnables.wait();
r = runnables.poll();
}
}
catch (InterruptedException ie) {
// Ignore it
}
if (r != null) {
r.run();
}
}
}
public void stopProcessing() {
running = false;
synchronized (runnables) {
runnables.notify();
}
}
public void addTask(Runnable r) {
synchronized (runnables) {
runnables.add(r);
runnables.notify();
}
}
}
Obviously, this is just an example. It would need to have better error-handling code, and perhaps more tuning available.
If you are concerned with the overhead of creating a new Thread object then you can use executors.
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
public class Testes {
public static void main(String[] args) {
Executor executor = Executors.newSingleThreadExecutor();
executor.execute(new Testes.A());
executor.execute(new Testes.A());
executor.execute(new Testes.A());
}
public static class A implements Runnable{
public void run(){
System.out.println(Thread.currentThread().getId());
}
}
}
Running this you will see that the same thread is used for all Runnable objects.
A Thread is not a thread. A thread is an execution of your code. A Thread is an object that your program uses to create and, manage the life-cycle of, a thread.
Suppose you like playing tennis. Suppose you and your friend play a really awesome set. How would your friend react if you said, "That was incredible, let's play it again." Your friend might think you were nuts. It doesn't make sense even to talk about playing the same set again. If you play again you're playing a different set.
A thread is an execution of your code. It doesn't make sense to even talk about "re-using" a thread of execution for same reason that it makes no sense to talk about re-playing the same set in tennis. Even if another execution of your code executes all the same statements in the same order, it's still a different execution.
Andrzej Doyle's asked, "Why would you want to re-use a Thread?" Why indeed? If a Thread object represents a thread of execution---an ephemeral thing that you can't even talk about re-using---then why would you want or expect the Thread object to be re-useable?
i've been searching the same solution which you seem to be looking for, and i resolved it in this way. if you occur mousePressed Event you can terminate it also reuse it, but it need to be initialized, as you can see below.
class MouseHandler extends MouseAdapter{
public void mousePressed(MouseEvent e) {
if(th.isAlive()){
th.interrupt();
th = new Thread();
}
else{
th.start();
}
}
}

Java: Is it common practice to create a new Thread when a lock is held?

I've got a question related but not identical to my first question ever here:
Java: what happens when a new Thread is started from a synchronized block?
Is it a common practice to create and start() a new Thread when you're holding a lock?
Would that be a code smell?
Basically I've got a choice between doing this:
public synchronized void somemethod() {
(every time I find a callback to be notified I start a thread)
Thread t = new Thread( new Runnable() {
void run() {
notifySomeCallback();
}
}
t.start();
...
(lengthy stuff performed here, keeping the lock held)
...
}
or this:
public void somemethod() {
(create a list of callbacks to be notified)
synchronized(this){
(potentially add callbacks)
...
(lengthy stuff performed here, keeping the lock held)
...
}
(notify the callbacks without holding a lock and once
we know the lock has been released)
}
I think the latter is better but I wanted to know if there
are cases where the first option would be ok? Do you sometimes
do that? Have you seen it done?
answer3:
You should always hold on to a lock as short as possible. So only the resource which is potentially referenced to from multiple threads should be locked for the smallest amount of time when the chance of a 'corrupt' resource exists (e.g. the writer thread is updating the resource)
Don't spin off a thread for every little thing which needs to be done. In the case of your callback threads, have 1 callback thread work off a queue of things to do.
You are aware that the two code snippets will result in different execution orders.
The first one will run the callbacks asynchronously, while the lengthy stuff is being performed. The second one will finish doing the lengthy stuff first and then call the callbacks.
Which one is better depends on what the callbacks need to do. It might well be a problem if they need lengthy stuff to be done first.
Who is waiting on the lock?
If the callbacks need the lock to run, it makes little sense to fire them, while you still hold the lock. All they would do is just wait for lengthy stuff to be done anyway.
Also, in the first snippet, you have one thread per callback. The second snippet is not explicit, but if you have only one thread for all of them, this is another difference
(whether the callbacks run simultaneously or in sequence). If they all need the same lock, you might as well run them in sequence.
If you want to run many callbacks with one or more threads, consider using an Executor instead of managing the threads yourself. Makes it very easy to configure an appropriate number of threads.
It depends on whether or not you want the callbacks to be executed concurrently with the lengthy stuff or not. If we are talking about a Swing GUI, option 1 is not good, because you shouldn't do Swing operations in several concurrent threads, so I propose the following:
public void somemethod() {
Thread t = new Thread( new Runnable() {
void run() {
doLengthyStuff();
}
}
t.start();
(notify the callbacks)
}

Categories

Resources