Use ReentrantLock and ReentrantReadWriteLock for thread synchronization.
package org.ocera.orte.demo;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
+
import org.ocera.orte.DomainApp;
import org.ocera.orte.Subscription;
import org.ocera.orte.SubscriptionCallback;
private HokuyoScanType hokuyomsg;
private DomainApp domainApp;
private SubsProp subProps;
+
private boolean isCancelled = true;
+ private final ReentrantReadWriteLock controlRrwl = new ReentrantReadWriteLock(true);
+ private final ReadLock rcLock = controlRrwl.readLock();
+ private final WriteLock wcLock = controlRrwl.writeLock();
public HokuyoScanSubscribe(DomainApp domainApp, HokuyoView view) {
this.view = view;
}
public void start() {
- isCancelled = false;
- sub = domainApp.createSubscription(subProps, hokuyomsg, this);
+ wcLock.lock();
+ try {
+ isCancelled = false;
+ sub = domainApp.createSubscription(subProps, hokuyomsg, this);
+ } finally {
+ wcLock.unlock();
+ }
}
public void cancel() {
- sub.destroy();
- isCancelled = true;
+ wcLock.lock();
+ try {
+ isCancelled = true;
+ sub.destroy();
+ } finally {
+ wcLock.unlock();
+ }
}
public boolean isCancelled() {
- return isCancelled;
+ rcLock.lock();
+ try {
+ return isCancelled;
+ } finally {
+ rcLock.unlock();
+ }
}
public void callback(RecvInfo info, MessageData msg) {
package org.ocera.orte.demo;
+import java.util.concurrent.locks.ReentrantLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
+
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
private int[] data = new int[681];
private Paint paint = new Paint();
private Path path = new Path();
+
private boolean isRunning = false;
private boolean hasBeenDrawn = true;
+ private final ReentrantLock lock = new ReentrantLock();
+ private final ReentrantReadWriteLock controlRrwl = new ReentrantReadWriteLock(true);
+ private final ReadLock rcLock = controlRrwl.readLock();
+ private final WriteLock wcLock = controlRrwl.writeLock();
public HokuyoView(Context context, AttributeSet attrs) {
super(context, attrs);
+
+ paint.setStyle(Style.STROKE);
+ paint.setStrokeWidth(4);
+ paint.setColor(Color.BLACK);
+ paint.setAntiAlias(false);
}
@Override
protected void onDraw(Canvas canvas) {
- paint.setStyle(Style.STROKE);
- paint.setStrokeWidth(3);
- paint.setColor(Color.BLACK);
- paint.setAntiAlias(true);
-
- path.reset();
- if (isRunning) {
- path.moveTo(getWidth()/2, getHeight());
- for(int i = 0; i < data.length; i++) {
- double ang = HOKUYO_INDEX_TO_RAD(i);
- if((ang<(-HOKUYO_RANGE_ANGLE_LEFT/180.0*Math.PI))||((ang>(HOKUYO_RANGE_ANGLE_RIGHT/180.0*Math.PI)))) {
- continue;
- }
-
- data[i] /= 10;
- int x = (int)(getWidth()/2) - (int)(data[i] * Math.sin(HOKUYO_INDEX_TO_RAD(i)));
- int y = getHeight() -(int)(data[i] * Math.cos(HOKUYO_INDEX_TO_RAD(i)));
- path.lineTo(x, y);
+ rcLock.lock();
+ try {
+ if (isRunning) {
+ lock.lock();
+ try {
+ if (!hasBeenDrawn) {
+ path.reset();
+ path.moveTo(getWidth()/2, getHeight());
+ for(int i = 0; i < data.length; i++) {
+ double ang = HOKUYO_INDEX_TO_RAD(i);
+ if((ang<(-HOKUYO_RANGE_ANGLE_LEFT/180.0*Math.PI))||((ang>(HOKUYO_RANGE_ANGLE_RIGHT/180.0*Math.PI)))) {
+ continue;
+ }
+
+ data[i] /= 10;
+ int x = (int)(getWidth()/2) - (int)(data[i] * Math.sin(HOKUYO_INDEX_TO_RAD(i)));
+ int y = getHeight() -(int)(data[i] * Math.cos(HOKUYO_INDEX_TO_RAD(i)));
+ path.lineTo(x, y);
+ }
+ path.close();
+ hasBeenDrawn = true;
+ }
+ }
+ finally {
+ lock.unlock();
+ }
+ }
+ else {
+ path.reset();
}
- path.close();
+ canvas.drawPath(path, paint);
+ } finally {
+ rcLock.unlock();
}
- canvas.drawPath(path, paint);
- hasBeenDrawn = true;
}
public void run(boolean run) {
- isRunning = run;
+ wcLock.lock();
+ try {
+ isRunning = run;
+ } finally {
+ wcLock.unlock();
+ }
}
public void setData(int[] data) {
- if (hasBeenDrawn) {
- this.data = data.clone();
- hasBeenDrawn = false;
+ if (lock.tryLock()) {
+ try {
+ this.data = data.clone();
+ hasBeenDrawn = false;
+ }
+ finally {
+ lock.unlock();
+ }
postInvalidate();
}
}
package org.ocera.orte.demo;
+import java.util.concurrent.locks.ReentrantLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
+
import org.ocera.orte.DomainApp;
-import org.ocera.orte.JOrte;
import org.ocera.orte.Publication;
import org.ocera.orte.types.NtpTime;
import org.ocera.orte.types.PublProp;
public static final double r = 0.15;
private short[] speed = new short[2];
- private boolean isCancelled = false;
- private boolean isSent = true;
+ private boolean isCancelled = true;
private float maxRange;
private float[] accelData = new float[2];
private SpeedMotionType speedmsg;
private PublProp publProp;
private DomainApp appDomain;
+ private final ReentrantLock dataLock = new ReentrantLock();
+ private final ReentrantReadWriteLock controlRrwl = new ReentrantReadWriteLock(true);
+ private final ReadLock rcLock = controlRrwl.readLock();
+ private final WriteLock wcLock = controlRrwl.writeLock();
+
public MotionSpeedPublish(float maxRange, DomainApp appDomain) {
this.maxRange = maxRange;
this.appDomain = appDomain;
"motion_speed",
persistence,
strength);
-
-
- }
-
- public void start() {
- isCancelled = false;
- pub = appDomain.createPublication(publProp, speedmsg);
- thread = new Thread(this);
- thread.start();
}
private void calculateSpeed(float[] mAccel) {
- double angle = 0, lenght, v, omega;
+ double angle = 0, length, v, omega;
v = (double)mAccel[1]/maxRange;
omega = (double)mAccel[0]/maxRange;
- lenght = Math.sqrt(Math.pow(v,2) + Math.pow(omega,2));
- if (lenght >= 1) {
+ length = Math.sqrt(Math.pow(v,2) + Math.pow(omega,2));
+ if (length >= 1) {
angle = Math.atan2(mAccel[1], mAccel[0]);
v = Math.sin(angle);
omega = Math.cos(angle);
speed[1] = (short)(-(v - (v>0 ? -r*omega : r*omega))*VMAX);
}
+ public void start() {
+ wcLock.lock();
+ try {
+ isCancelled = false;
+ pub = appDomain.createPublication(publProp, speedmsg);
+ thread = new Thread(this);
+ thread.start();
+ }
+ finally {
+ wcLock.unlock();
+ }
+ }
+
public void cancel() {
- isCancelled = true;
+ wcLock.lock();
+ try {
+ isCancelled = true;
+ rcLock.lock();
+ } finally {
+ wcLock.unlock();
+ }
try {
thread.join();
+ pub.destroy();
} catch (InterruptedException e) {
e.printStackTrace();
+ } finally {
+ rcLock.unlock();
}
- pub.destroy();
}
public boolean isCancelled() {
- return isCancelled;
+ rcLock.lock();
+ try {
+ return isCancelled;
+ } finally {
+ rcLock.unlock();
+ }
}
@Override
public void run() {
- while(!isCancelled) {
- calculateSpeed(accelData.clone());
- speedmsg.speed = this.speed.clone();
- pub.send(speedmsg);
- isSent = true;
- JOrte.sleepMs(100);
+ while(true) {
+ rcLock.lock();
+ try {
+ if (!isCancelled) {
+ dataLock.lock();
+ try {
+ calculateSpeed(accelData);
+ }
+ finally {
+ dataLock.unlock();
+ }
+ speedmsg.speed = this.speed;
+ pub.send(speedmsg);
+ }
+ else
+ break;
+ } finally {
+ rcLock.unlock();
+ }
+ try {
+ Thread.sleep(100);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
}
}
public void setSpeed(float accelX, float accelY) {
- if(isSent) {
- isSent = false;
- this.accelData[0] = accelX;
- this.accelData[1] = accelY;
+ if (dataLock.tryLock()) {
+ try {
+ this.accelData[0] = accelX;
+ this.accelData[1] = accelY;
+ }
+ finally {
+ dataLock.unlock();
+ }
}
}
-
}