newbie with thread problems

J

Jeff

midp 2.0
Java SE 5.0
J2ME version 2.2

I have some problems with threads. In this post I first list my trouble code
and beneath the code you will find my questions....

This is a thread i've created:
public class NetworkThread extends Thread
{
private boolean networkStop = false;
private String cmd = "";
public NetworkThread()
{
}

synchronized void requestStop()
{
networkStop = true;
notify();
}

public void setCommand(String cmd) {
this.cmd = cmd;
}

public void stop() {
networkStop = true;
}

public void run() {
while (!networkStop) {
System.out.println("NetworkThread");
}
}
}

A debug function:
private void testing () {
System.out.println("TESTING");
}
Here is my code that runs the thread above
NetworkThread networkThread = new NetworkThread();
networkThread.start();
testing();
networkThread.stop();

I wonder why the word NetworkThread isn't written out to the debug window
when running this code?....

I also tryed to modify the code a bit:
private void testing() {
System.out.println("getServerResonse A");
httpConnection = (HttpConnection) Connector.open(url);
rc = httpConnection.getResponseCode();
if (rc != HttpConnection.HTTP_OK) {
System.out.println("getServerResonse B");
loginForm.setInfo("ERROR");
throw new IOException("HTTP reponse code: " + rc);
}
System.out.println("getServerResonse C");
InputStream inputStream = httpConnection.openInputStream();
/*
THIS CODE IS A SIMPLIFIED VERSION OF A MUCH MORE COMPLEX CODE
*/
}

NetworkThread networkThread = new NetworkThread();
networkThread.start();
testing();
networkThread.stop();

This code generate this output in debug window:
getServerResonse A
NetworkThread
NetworkThread
NetworkThread
NetworkThread
NetworkThread
NetworkThread
NetworkThread
NetworkThread
(I cut the list of NetworkThread, I guess there was several hundreds of
them....)
getServerResonse B and getServerResonse C wasn't written out and it looks
like the midlet went into a loop where it only write NetworkThread to the
screen and did not let any other processes do their tasks... In addition to
not writing out getServerResonse B and getServerResonse C the midlet didn't
reponse to mouse click on emulator
What am I doing wring here?

Jeff
 
M

Matt Humphrey

Jeff said:
midp 2.0
Java SE 5.0
J2ME version 2.2

I have some problems with threads. In this post I first list my trouble
code and beneath the code you will find my questions....

I've interspersed some comments...
This is a thread i've created:
public class NetworkThread extends Thread
{
private boolean networkStop = false;
private String cmd = "";
public NetworkThread()
{
}

synchronized void requestStop()
{
networkStop = true;
notify();
}

public void setCommand(String cmd) {
this.cmd = cmd;
}

public void stop() {
networkStop = true;
}

public void run() {
while (!networkStop) {
System.out.println("NetworkThread");
}
}

Here you tell your thread to do nothing but iterate printing out a message.
This turns out to be exactly what it does. What did you really want your
thread to do?

Also, your networkStop conditional test is not in a synchronized block so it
will not see any updates to the flag in a timely manner (or possibly at
all). That is, your thread will be reading a cached version of
"networkStop" and when your reqeustStop method sets it to true, the cache
will not necessarily be updated right away. (Same with your stop method)
}

A debug function:
private void testing () {
System.out.println("TESTING");
}
Here is my code that runs the thread above
NetworkThread networkThread = new NetworkThread();
networkThread.start();
testing();
networkThread.stop();

I wonder why the word NetworkThread isn't written out to the debug window
when running this code?....

You're saying it prints nothing, but later you say it prints NetworkThread
repeatedly. Which is it? Are you sure the code you've shown is being
executed? The only way this code would not generate output here, but
produce output later (after you changed the testing method) is because you
also changed something else you're not showing.
I also tryed to modify the code a bit:
private void testing() {
System.out.println("getServerResonse A");
httpConnection = (HttpConnection) Connector.open(url);
rc = httpConnection.getResponseCode();
if (rc != HttpConnection.HTTP_OK) {
System.out.println("getServerResonse B");
loginForm.setInfo("ERROR");
throw new IOException("HTTP reponse code: " + rc);
}
System.out.println("getServerResonse C");
InputStream inputStream = httpConnection.openInputStream();
/*
THIS CODE IS A SIMPLIFIED VERSION OF A MUCH MORE COMPLEX CODE
*/
}

NetworkThread networkThread = new NetworkThread();
networkThread.start();
testing();
networkThread.stop();

This code generate this output in debug window:
getServerResonse A
NetworkThread
NetworkThread
NetworkThread
NetworkThread
NetworkThread
NetworkThread
NetworkThread
NetworkThread
(I cut the list of NetworkThread, I guess there was several hundreds of
them....)
getServerResonse B and getServerResonse C wasn't written out and it looks
like the midlet went into a loop where it only write NetworkThread to the
screen

Why are you surprised at this? You put the message in a loop.
and did not let any other processes do their tasks... In addition to not
writing out getServerResonse B and getServerResonse C the midlet didn't
reponse to mouse click on emulator
What am I doing wring here?

The problem here is how you think about what the thread is doing. As far as
I can tell it's working fine. What you need to realize is that your
"NetworkThread" message is in a tight loop with nothing to slow it it down.
It will generate huge amounts of output as fast as possible. Your other
method, however, because it opens a URL, will be busy for a few seconds
before it makes it to the next output statement. In that time the first
loop will generate thousands upon thousands of lines of output. You won't
see any output until that new message comes through. If the URL has a
problem, it can take a very long time to get a response.

What are you really trying to make it do?

Cheers,
Matt Humphrey (e-mail address removed) http://www.iviz.com/
 
J

Jeff

Hey Matt!

Thanks for your post I'm studing my code again based on what you wrote....

I've created a midlet that commandAction accesses the internet... I code
block in commandAction accesses a server on internet and waits for a
response from the server. This works okay when testing on Nokia mobiles, but
when testing on SonyEricsson emulators the emulator hang and KToolbar gives
a message telling that is not a good idea to do a lenghty processes on the
same thread as commandAction...

I thought about design this so that when commandAction calls another thread
to the internet access, and while this method was busy with the internet
access the commandAction was responsive for other tasks, such as exiting the
midlet
Thought? Is this possible?

I'm a newbie in threads so first I'm trying to develop my skills for using
threads in java before I implement threads in my midlet...
 
M

Matt Humphrey

Jeff said:
Hey Matt!

Thanks for your post I'm studing my code again based on what you wrote....

I've created a midlet that commandAction accesses the internet... I code
block in commandAction accesses a server on internet and waits for a
response from the server. This works okay when testing on Nokia mobiles,
but when testing on SonyEricsson emulators the emulator hang and KToolbar
gives a message telling that is not a good idea to do a lenghty processes
on the same thread as commandAction...

I thought about design this so that when commandAction calls another
thread to the internet access, and while this method was busy with the
internet access the commandAction was responsive for other tasks, such as
exiting the midlet
Thought? Is this possible?

In general it's a good idea for a GUI tooff load long tasks to a thread.
You would normally have GUI operations to start and stop the action as well
as a means to show progress and results. I don't know what the constraints
are on your midlet or how you might need to structure it for your particular
application. I'll show how it works for a Swing-style GUI.

I'm a newbie in threads so first I'm trying to develop my skills for using
threads in java before I implement threads in my midlet...

Doug Lea's book is quite good. Threads themselves are easy, but in order to
be useful you have to work out correct synchronization, which is very
difficult and fraught with traps. Working out small tests is a good idea,
so I've put in some comments below as to what would be good things to try.
Java 5/1.5 includes utilities for simplifying much of what you're
doing--check out the Executor interface

For this exercise, you can change your run as follows:

public void run () {
try {
while (true) {
synchronized (this) {
this.wait (1000);
if (networkStop) break;
}

System.out.println ("NetworkThread");
}
} catch (InterruptedException ex) {
ex.printStackTrace ();
}
}

This will print your message at a much slower rate, properly wrap your
access to networkStop in a synchronization block for timely update and have
a wait that is signalled by the request to stop. This test works with your
original test that adds comments (realizing that your testing() method is
not executing in the same thread.)

It's ok to work out your internet access method body first without using a
thread to make sure you can reliably make a connection and return results.
When you're ready just put it into the run method. Of course, your real
work does not have a loop and won't respond to networkStop in the same way.
You may need some kind of extra technique to make sure that the run task
eventually stops.

The last part is for your thread to signal the GUI that it's done. Your
thread should have some kind of reply interface that it calls back on signal
that it's done. Minimally, something like:

interface IReply {
void done (String result);
}

When you create your thread in your commandAction you also supply an
implementation of IReply (or make your GUI implement IReply). The code body
for that then reads off the result and displays it. In Swing, this means
that the reply must be handed off to the event dispatch thread so that it
remains threadsafe, as in:

IReply replyHandler = new IReply () {
void done (String result) {
SwingUtilities.invokeLater (new Runnable () {
public void run () {
// Update the GUI with the received result
}
} );
}
};

// Add the reply handler as a parameter to your thread
NetworkThread networkThread = new NetworkThread (replyHandler);
networkThread.start ();


At the end of your run method you would say
replyHandler.done ("Whatever the result is");

Unless your GUI is in Swing, your midlet will require some other approach to
displaying asynchronous results.

Good luck,
Matt Humphrey (e-mail address removed) http://www.iviz.com/
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,770
Messages
2,569,586
Members
45,088
Latest member
JeremyMedl

Latest Threads

Top