If this is your first visit, be sure to
check out the FAQ by clicking the
link above. You may have to register
before you can post: click the register link above to proceed. To start viewing messages,
select the forum that you want to visit from the selection below.

Thread..

I have never seen that way of implementing a thread (or two).
Here is a bare-bone example:

Code:

public class ThreadExample implements Runnable {
Thread t1=null;
Thread t2=null;
private boolean t1IsRunning=false;
private boolean t2IsRunning=false;
public ThreadExample() {
}
public void gogogo() {
t1=new Thread(this); // not started yet....
t2=new Thread(this); // not started yet....
setT1IsRunning(true); // not started yet....
setT2IsRunning(true); // not started yet....
t1.setPriority(Thread.NORM_PRIORITY); // not started yet....
t2.setPriority(Thread.NORM_PRIORITY); // not started yet....
t1.start(); // STARTED
t2.start(); // STARTED
}
/**
* Thread control methods
*/
private synchronized boolean getT1Running() {
return t1IsRunning;
}
private synchronized void setT1IsRunning(boolean t1IsRunning) {
this.t1IsRunning=t1IsRunning;
}
private synchronized boolean getT2Running() {
return t2IsRunning;
}
private synchronized void setT2IsRunning(boolean t2IsRunning) {
this.t2IsRunning=t2IsRunning;
}
public void heavy_math1(int x, int y, int z) {
/**
* Do some heavy math....
*/
setT1IsRunning(false); // then finish
return;
}
public void heavy_math2(int x, int y, int z) {
/**
* Do some heavy math....
*/
setT2IsRunning(false); // then finish
return;
}
/**
* This method is called from the java VM. If you call it from within the
* code of a class it will not be a thread....
* The java VM runs this in 'bursts'
* lending the cpu power to the threads in a round-robin fashion.
* - if you view the processing performed by the two heavy_math -methods
* as two sequences (threads) of statement executions, then the processing done
* by heavy_math1 is halted (in its 'tracks') while heavy_math2 is allowed to
* continue.
*
* If you want to set or get any values that are used by the threads you must
* do it via synchronized methods, like the control methods above. Remember,
* synchronization has a bill to pay in cpu-power, so it should not be used
* unless it is required.
*
* If the heavy_math methods access progressbars (or any other vizualization
* components) in the GUI, then they will be responsive, since the GUI is
* under the control of the applications main thread, wich is also executed in
* bursts by the java VM.
*
* NOTE: avoid Thread.MAX_PRIORITY, unless you want to block out your PC....
*/
public void run () {
if (Thread.currentThread()==t1) {
while (getT1Running()) {
heavy_math1(1,2,3);
}
return; // the death of t1
} else if (Thread.currentThread()==t2) {
while (getT2Running()) {
heavy_math2(4,5,6);
}
}
return; // the death of t2
}
public static void main(String[] args) {
ThreadExample te = new ThreadExample();
te.gogogo();
}
}

What rechmbrs is doing is defining and instantiating an inner class that implements the interface Runnable "in one shot". But he does not start any thread which you (afterwards) would do like

Code:

new Thread(HM).start();

This is correct java syntax although not good style (referring to instances with upper case starting names). It is kind of a shortcut for first defining an inner class like

Code:

(static) class MyRunnable {
public void run {
//heavy math here
}
}

(in the scope of the enclosing class)
and afterwards instantiating it like

Code:

Runnable HM = new MyRunnable();

(in the scope of a (static) method). See, I had to introduce the name "MyRunnable" I'd never use again. That's the savings you make with the shortcurt.

So the answer to the original question

Is this all I need to do to make them runnable in their own threads?

...is: yes. You made it runnable; you'd only have to start a Thread that executes this Runnable now.
The purpose of the Runnable interface is to provide a means to have classes executed as threads that cannot subclass Thread eg. because they need to subclass some other class (there is no multiple inheritance in java).

You even do not need the class to be named; you can use an anonymous one like

Code:

new Thread(
new Runnable() {
public void run() {
System.out.println("doing my best to do heavy math stuff");
}
}
).start();

in a method to start a thread executing your heavy math stuff concurrently.

---

Making your threads behave "civilized", ie. the way you want them to behave/interact, is quite a different topic and non-trivial. Stopping threads you do as sjalle has shown (DO NOT use Thread.stop() and the like! They're deprecated for a reason).
But as long as it's simply about reading access like for a JProgressBar where it is non-vital to see an object in a consistent state (that state is obsolete the very second after) or you even access only primitive type attributes (access to which is atomic anyway*) no synchronisation at all is required.

If that's all you want to do, then it's fine. For the more sophisticated situations there has been done quite some brainwork; look at the results of this brainwork in the concurrency API java.util.concurrent (since 1.5) and decide yourself.

---
*footnote: that's why sjalle's way to stop a thread is the recommended one and working.

Just one thing:

I don't like inner classes, cause I don't like bloated syntax. I think adapters
suck too and I really hope that Java doesn't end up like C++.... But then
again, I'm just an old fart that spent his first 15 years of programming coding
Fortran.

The documentation on why the stop() method is deprecated is still
at the same place as the doc for the java.lang.Thread.stop() method.

PS: My synchronization habit is from 16 bit computing, when you ran the risk
of halting a thread while it was busy processing a 32 bit primitive, - only
half of the value could ride the bus at one time.

Meisl,
I started the thread asking about heavymath/cpu routines and finally got something that seems to work from the standpoint of using another thread but the equivalent code trying to put JProgressBar calls still doesn't work. Am I missing something?

FYI. I programmed in Fortran until 2002 and started way back in 1959 with Fortran II on an IBM 1620.

little demo to play around with

Hey Ron,
I have put together a little demo that uses various threads, two of them doing "heavy math stuff". The progress of these two is displayed via JProgressBars and there are buttons to start, stop, suspend, resume one or both. On STDOUT it prints messages about what happens including information in which thread something happened.

The methods stop(), suspend() and resume() in class HeavyMathCalculator implement the suggested patterns while avoiding Thread.stop(), Thread.suspend() and Thread.resume().

I'm sorry that all is quite complicated, but maybe you can nonetheless adapt it for your purpose. It's grown out of size mostly because of those bloody buttons, that you would not need in your app I guess.
In any case, I'd like to recommend the chapters on Threads and Progress Bars in the Java Tutorial, that may be easier to understand than the technical papers, including the javadoc on Thread primitive deprecation.

There is a built-in test in this demo:
After it has started, click the following buttons:
1. "start/resume both"
2. "math1.stop()"
3. "suspend both"
4. "math1.resume()"
What is going on here?! Can you repair this?

Well, maybe I should add that in fact there is a general flaw in my conceptual design of the buttons...

Anyways, have fun with it.

p.s.: I'm still interested in what your heavy math stuff is calculating.

My program is different in that the dialog is built and buttons on it tell what to do. The program is like an image editing program but has a very special use.

My heavymath ranges from simple convolution to iterations of random numbers then convolution then tied to the image. I'd be willing to send the code (somewhat large) put prefer it not be spread around. If interested, send me a message.

Anyway, you're quite right wrt to Thread.sleep() vs Thread.yield(), sjalle. It's fine and much less typing - when it's all about equal-priority threads. But if you have threads with (possibly*) different priorities, you cannot give a lower-prioritized thread the chance to execute via Thread.yield(). This is due to java's so-called fixed-priority thread scheduling algorithm. The same goes for no precaution at all in your code: only threads with the same priority as the currently executing thread eventually get a chance - and if a thread with higher priority becomes runnable, none of the former will be executed as long as the higher-prioritized thread has finished.
So sleep() is the most general approach and that's why I used it in the demo.

Well, and of course I have indeed been too lazy to facilitate some heavy math, so you're completely right with regard to the progress bars/Thread.sleep(). I had been thinking about tweeking the whole thing with Mandelbrot set computation - a perfectly parallelizable problem - but that would have led way too far in this context I guess.

GUI-from-event-dispatching-thread-thing:
I have not fully understood this myself, but I did occasionally experience the deadlocks they're talking about when doing GUI-stuff from the main thread. It has something to do with modifying (swing-)components that had already been "realized" (mainly: painted onscreen); where modifying even includes eg changing the contents of a text-field. Such deadlocks typically manifest themselves in an app getting stuck at startup with no window coming up (ie. sometimes, as with most effects related to concurrency).
For a similar reason I use invokeAndWait() instead of invokeLater(), although it admittedly looks quite odd; even more with the possible exceptions to catch...
Note that I do start() the demo from the main thread (hence the thread that polls the HeavyMathCalculators is a child of main), where components are eventually modified. That's ok, problems seem to occur if you do both, creation ("realization") AND modification of the components from main, or: creation from main and modification from event-dispatch, eg in an event handler.
Additionally, with Win98 and older JDKs, I had a queer effect on the cpu usage display: it was always at 100%, even if nothing was done except waiting for some input event. Doing the GUI stuff from the event-dispatch thread fixed it. However, since 1.4 (if I recall it correctly), this behaviour does not occur anymore.
But as already said, all that I don't really understand.

Ah, and hey: there is no new Thread that creates the GUI. The event-dispatching thread is always there when using awt/swing. The new thread (as mentioned this is a child of main), that changes the GUI - well this one isn't essential. But while we're at it I thought...

---------------
* footnote: at last, a thread's priority can change during its life cycle

@Ron:
I didn't get in what your program is (principally) different. There are buttons to click in the demo as well... Ok, doesn't seem too important.
Your image manipulation stuff sounds interesting. I have seen that you asked some questions about JAI elsewhere here - and that there hasn't been much of a response. I've been playing around with that some time ago but didn't do anything big. Especially that rendering-graph paradigm or what's it called I found interesting. I heard there's a major revision of JAI out now, 2.0 or so.
Well, enough of chatting around. Was the demo of any help for you?