I hava a Java-controlled robot. It has an ultrasonic sensor that is rotated back and forth by Motor B.
Normally, I have a separate thread that scans the environment and sends the collected data to another machine in order to draw a map.
However, sometimes the main thread needs to briefly use the sensor to look in a specific direction.
Here's my scanner thread:
public void run() {
while (!stop) {
Motor.B.forward();
while (Motor.B.getTachoCount() < 90 && !stop) {
try{Thread.sleep(20);} catch (InterruptedException ex) {ex.printStackTrace();}
Mapperbot.sendCommand("S US "+sonic.getDistance()+" "+Motor.B.getTachoCount());
}
Motor.B.backward();
while (Motor.B.getTachoCount() > -90 && !stop) {
try{Thread.sleep(10);} catch (InterruptedException ex) {ex.printStackTrace();}
}
}
Motor.B.stop();
}
And here's the "tell me the direction now" function, it belongs to the same class:
public synchronized int getDistanceInDirection(int direction) {
Motor.B.rotateTo(direction);
return sonic.getDistance();
}
The required behavior: Whenever "getDistanceInDirection" is called, it must briefly stop scanning and turn to the given direction, return the distance, and continue scanning.
What is the correct way to tell my scanner thread for the time it takes to execute the second function?
I would use a semaphore:
final Semaphore semaphore = new Semaphore(1);
//in the scanner thread
semaphore.acquire();
try {
while (! stop) {
semaphore.release();
semaphore.acquire();
...use sensor...
} finally {
semaphore.release();
}
//in the main thread
semaphore.acquire();
try {
...use sensor...
} finally {
semaphore.release();
}
Throw in a synchronized(this)
public void run() {
while (!stop) {
synchronized(this) {
Motor.B.forward();
while (Motor.B.getTachoCount() < 90 && !stop) {
try{Thread.sleep(20);} catch (InterruptedException ex) {ex.printStackTrace();}
Mapperbot.sendCommand("S US "+sonic.getDistance()+" "+Motor.B.getTachoCount());
}
Motor.B.backward();
while (Motor.B.getTachoCount() > -90 && !stop) {
try{Thread.sleep(10);} catch (InterruptedException ex) {ex.printStackTrace();}
}
}
}
Motor.B.stop();
}
Which will then ensure that the loop contents and getDistanceInDirection never run simultaneously
Related
I have come up with following thread 'halo' to make it connect to db (redis, in this case) and in the event that server fails, would wait for a second and try again. In my unit test class, method is executing, and not long after new thread starts, server will fail. But then this new thread 'halo' is immediately shut down. What am I doing wrong?
// almost infinitely large number of sets, interrupted by server seg-fault
// you gotta try company methods
Thread halo = new Thread(new Runnable() {
#Override
public void run() {
int count = 0;
while (count < Integer.MAX_VALUE) {
if (JedisPoolFactory.getStatus()) {
try {
for (int i = 0; i < 10000; i++) {
master.set(String.format("key_%d", count), String.format("value_%d", count));
System.out.println(master.get(String.format("key_%d", count)));
count++;
}
} catch (JedisConnectionException igr) {
try {
Thread.sleep(1000);
} catch (InterruptedException ignore) {}
}
} else {
try {
Thread.sleep(1000);
} catch (InterruptedException ignrod) {}
}
}
}
});
halo.start();
try {
master.debug(DebugParams.SEGFAULT());
halo.join();
} catch (JedisConnectionException ignored) {
} catch (InterruptedException igr) {}
thread joining should be done outside of exceptions, when master goes segfault it invokes jedisconnectionexception.
Given code is working in doInBackground(). Where while loop is always true but i don't know how it calls other methods in catch.
Can someone explain me the technique and how can we benefit with this technique. I don't know how and when we get out of the loop.
doInBackground
if(isRunning)
{
while (true) //this loop should run always.
{
try
{
Thread.sleep(1L);
}
catch (InterruptedException ex)
{
Log.e("Testing Interuption", "error=" + ex.getMessage());
// some working here is also running
}
}
}
Can it call any statement after while or not? I mean can it also get out of while loop or not.
Edit
When did the Interuption Occur.It means when another AsyncTask is calling Thread.sleep(); it will interupt(means go to catch). Am I right?
I am calling Multiple AsyncTasks to set a CameraPreview using Bitmap.
#TargetApi(11)
public void start()
{
if (Build.VERSION.SDK_INT >= 11)
{
executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, new Void[0]);
return;
}
execute(new Void[0]);
}
The while (true) statement will never end, since there's nothing to break out of the loop, so no, it can not get out of the while loop. (Depends on what's in // some working here is also running though.)
The code in the catch statement is executed if another thread sends an interrupt to this thread. When the code has been executed under catch the while loop re-starts again.
If you want to break out of the while loop if an InterruptedException is received, add a break; statement inside the catch.
It can call anything, as long as you break out of your loop, like this:
if (isRunning) {
while (true) //this loop should run always.
{
try {
Thread.sleep(1L);
}
catch (InterruptedException ex) {
Log.e("Testing Interuption", "error=" + ex.getMessage());
// some working here is also running
break; // <--
}
}
doStuffAfterWhileLoop();
}
i wrote some code, which should help you to understand how it is working.
public class Test2 {
boolean doBreakOut = false;
public Test2() {
Runnable runnable = new Runnable() {
#Override
public void run() {
while (true) // this loop is running while
// !(doBreakOut == true && isInterrupted()).
{
try {
Thread.sleep(1L);
} catch (InterruptedException ex) {
// this is executed when interrupt() is called.
if (doBreakOut) {
break;
}
System.out.println(("Testing Interuption -> "
+ "error=" + ex.getMessage()));
}
}
System.out
.println("did leave loop, threat will shut down now.");
}
};
try {
Thread threat = new Thread(runnable);
threat.start();
// Thread.sleep(x) makes the main thread wait for x milliseconds
Thread.sleep(2000);
threat.interrupt();
Thread.sleep(2000);
threat.interrupt();
Thread.sleep(2000);
doBreakOut = true;
threat.interrupt();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
new Test2();
}
}
As the title describes, I have a View class in which I need to reach out to get some data via TCP before I update the drawing. When I implemented this in my usual new Thread()...start() construction Eclipse whined at me about instantiating something new in an onDraw() method. In response to that, I reconfigured my thread as a class variable and I'm attempt to execute t.start() in the onDraw() loop.
However, there must be some thread baby-sitting I'm not aware about because my code is throwing an exception (java.lang.IllegalThreadStateException: Thread already started) when it attempts to start the thread the second time. The following is the current version of my code:
Thread t = new Thread()
{
public void run()
{
try
{
String st1 = getNetwork(); // Get network information
if (null != st1)
{
String[] st = st1.substring (st1.indexOf (' ') + 1, st1.length()).split (",+");
setNeighbors (st.length);
for (String s:st)
{
Log.e (TAG, s.trim());
String[] t1 = s.trim().split ("\\s+");
numbers.add (t1[0]);
addresses.add (t1[1]);
states.add (t1[2]);
}
}
}
catch (Exception ex)
{ }
finally
{
NetworkView.this.wait = false;
}
}
};
#Override
protected void onDraw (final Canvas canvas)
{
if (++drawCtr % 300 == 0)
{
this.wait = true;
t.start();
while (wait);
try
{
t.join();
}
catch (InterruptedException e) { }
}
update (canvas);
try { Thread.sleep (50); }
catch (InterruptedException e) { }
invalidate();
}
I get that the 2nd time around, my thread has already been started. How do I "reset" or "unstart" it for a 2nd attempt??
As Henry pointed out, my initial concept was a bad idea. A much more workable architecture was to have the TCP thread control the redraw, rather than having the redraw thread control the TCP data exchange, especially because there's no need (at least in my case) to redraw the screen between TCP updates. Hence, I implemented this thread in my View object's constructor:
(new Thread()
{
public void run()
{
while (looping)
{
try
{
// Get the important data via TCP (CAN'T be on the UI thread)
String st1 = tcpClient.getNetwork();
String st2 = tcpClient.getDiscovery();
}
catch (Exception ex)
{ }
finally
{
try
{
// Redraw the display (HAS TO be on the UI thread)
net.runOnUiThread (new Runnable()
{
#Override
public void run()
{
invalidate();
}
});
}
catch (Exception ex)
{ }
try { Thread.sleep (2000); }
catch (InterruptedException e) { }
}
}
}
}).start();
The key is the invalidate() call in the finally block (that needs to be run on the UI thread). That will update the screen based on the fresh new information.
I am a beginner and I was analyzing this java code:
// t is a thread running
while (true) {
try {
t.join();
} catch (InterruptedException e) { e.printStackTrace(); }
break;
}
t=null;
What I am asking is: is there a need to put that inside an infinite loop? Because as I see the loop will run only once i.e due to that break statement. I need some explanation please.
No, there's no need. Your observation is correct, the loop will be executed only once.
So the OP-posted code is equivalent to the following code.
// t is a thread running
try {
t.join();
} catch (InterruptedException e) { e.printStackTrace(); }
t=null;
Code posted by OP:
// t is a thread running
while (true) {
try {
t.join();
} catch (InterruptedException e) { e.printStackTrace(); }
break;
}
t=null;
As everyone has already pointed out, the code is incorrect as it stands.
The loop, however is necessary!
The correct code looks like this:
while (true) {
try {
t.join();
break;
} catch (InterruptedException e) { e.printStackTrace(); }
}
t = null;
Without the loop, it is possible for t to be set to null, before the current thread successfully joins it.
t.join(); waiting the finishing of thread.
After that, loop is broken by your "break".
=> always loop only 1 time => no need loop and break, only need t.join();
No need to have a while loop, because t.join() waits for the thread to die.
is like a loop already, in the program at the line of t.join() the program will be blocked while the thread is not dead.
The correct code is:
// t is a thread running
try {
t.join();
} catch (InterruptedException e) { e.printStackTrace(); }
t=null;
Here you have an example :
http://www.tutorialspoint.com/java/lang/thread_join.htm
Loop is not necessary!.
It is said that thread t is already started. Therefore it makes no sense "t=null". Thread t is already started and it will finish its job. You can use t.join() without while loop. In this context while loop does not make sense. The join method allows one thread to wait for the completion of another. If t is a Thread object whose thread is currently executing,
t.join();
causes the current thread(main thread in below example) to pause execution until t's thread terminates.Run following code snippet and know the ropes.
public class Main {
public static void main(String[] args) {
Thread t=new Thread(
new Runnable() {
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println(Thread.currentThread().getName()+"--"+i);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
});
t.start();
try {
t.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
t = null; // no sense, t is already started
for (int i = 0; i < 100; i++) {
System.out.println(Thread.currentThread().getName()+"--Thread--"+i);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
class myThreadRun implements Runnable
{
public void run() {
roo();
}
public synchronized void roo()
{
System.out.println("In thread before wait " + Thread.currentThread().getName());
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
JOptionPane.showMessageDialog(null, "After wait in\n"+Thread.currentThread().getName());
System.out.println("In thread after wait " + Thread.currentThread().getName());
//notify();
}
public synchronized void foo()
{
notify();
}
}
public class ThreadingDemo {
public synchronized void Start()
{
System.out.println("Labamba");
myThreadRun mThRun = new myThreadRun();
Thread thread = new Thread(mThRun);
thread.start();
try {
Thread.sleep(1000);
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
//mThRun.foo(); //This works
//mThRun.notify(); //crash
//thread.notify();//crash
try {
thread.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void main(String[] args) {
new ThreadingDemo().Start();
}
This is simple code to demonstrate wait() and notify(),
In the myThreadRun class run() method just does wait() and foo() method does notify()
as indicated in the code above, if I do mThRun.notify() the program crashes, but mThRun.foo() runs the without a hitch and gives the much needed result. I need to know why?
You need to own the monitor for the object to all obj.wait() and obj.notify().
That is why it works when called within the synchronized block on mThRun but not outside. So if you put the mThRun.notify(); in a synchronized block, it works, like this:
synchronized (mThRun) {
mThRun.notify();
}
In your case you are getting an IllegalMonitorStateException.
Thrown to indicate that a thread has attempted to wait on an object's monitor or to notify other threads waiting on an object's monitor without owning the specified monitor.
Put another way, you don't hold the lock of the object you are trying to notify. Having the lock of a different object doesn't help.
When you use notify() and wait() you need to change a state and check for it. If you don't do this, you can find that either
notify() is called before wait() and the signal is lost
wait() wakes prematurely
You cannot assume notify/wait is a reliable messaging protocol.
I suggest you consider using the concurrency library which is a better choice in most cases from Java 5.0 (2004)
May be you are going very hard with wait/notify. Its very simple. what you need to know is which object is used for monitor lock. To make the same code working i have modified the same code: ( I have put MAK comment where i changed the code, hope its helpful)
class MyThreadRun implements Runnable {
public void run() {
roo();
}
public synchronized void roo() {
System.out.println("In thread before wait " + this);
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
JOptionPane.showMessageDialog(null, "After wait in\n" + Thread.currentThread().getName());
System.out.println("In thread after wait " + Thread.currentThread().getName());
}
}
public class ThreadingDemo {
public static void main(String[] args) {
MyThreadRun mThRun = new MyThreadRun();
System.out.println("Labamba: " +mThRun);
Thread thread = new Thread(mThRun);
thread.start();
try {
Thread.sleep(100);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
//mThRun.foo(); //This works //MAK: no sense
//mThRun.notify(); //crash //MAK: Need monitor lock
synchronized (mThRun) {
mThRun.notify();//crash //MAK: will work now
}
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}