我的问题是:如何从其他线程访问值?
我有两个.java文件,Main.java和TrackHands.java
Main.java
/**
* This is the main class, it is used to start the program. The only use of this
* is to make everything more organized.
*/
package Kinect;
//import processing.core.PApplet;
/**
* @author Tony Nguyen <Tony.Nguyen@HvA.nl>
*
*/
public class Main
{
public static void main(String _args[])
{
Thread trackHands = new Thread(new TrackHands());
trackHands.start();
}
}
TrackHands.java
/*
* This uses the normal Java layout to track the user and prints out the coordinates of the left and right hand
*/
package Kinect;
import SimpleOpenNI.*;
import processing.core.PApplet;
import processing.core.PVector;
/**
* @author Tony Nguyen <Tony.Nguyen@HvA.nl>
* @version 1.0
*/
public class TrackHands extends PApplet implements Runnable
{
private int handLeftX, handLeftY = 0; // Holds the coordinates of the left hand
SimpleOpenNI kinect = new SimpleOpenNI(this); // kinect object
/**
* Constructor Takes no parameters
*/
public TrackHands()
{
}
/**
* run This will be executed when the thread starts
*/
@Override
public void run()
{
IntVector userList = new IntVector(); // Make a vector of ints to store the list of users
PVector leftHand = new PVector(); // Make a vector to store the left hand
PVector convertedLeftHand = new PVector();
kinect.enableDepth();
kinect.enableUser(SimpleOpenNI.SKEL_PROFILE_ALL);
kinect.setMirror(true);
while (true)
{
kinect.update();
kinect.getUsers(userList); // Write the list of detected users into the vector
if (userList.size() > 0) // Checks if a user is found
{
int userId = userList.get(0); // Get first user
if (kinect.isTrackingSkeleton(userId)) // If successfully calibrated
{
kinect.getJointPositionSkeleton(userId,
SimpleOpenNI.SKEL_LEFT_HAND, leftHand); // Put the position of the left hand into that vector
kinect.convertRealWorldToProjective(leftHand,
convertedLeftHand);
this.handLeftX = round(convertedLeftHand.x);
this.handLeftY = round(convertedLeftHand.y);
}
}
}
}
// User-tracking callbacks!
public void onNewUser(int userId)
{
System.out.println("Start pose detection");
kinect.startPoseDetection("Psi", userId);
}
public void onEndCalibration(int userId, boolean successful)
{
if (successful)
{
System.out.println(" User calibrated !!!");
kinect.startTrackingSkeleton(userId);
} else
{
System.out.println(" Failed to calibrate user !!!");
kinect.startPoseDetection("Psi", userId);
}
}
public void onStartPose(String pose, int userId)
{
System.out.println("Started pose for user");
kinect.stopPoseDetection(userId);
kinect.requestCalibrationSkeleton(userId, true);
}
}
我尝试使用getter和setter将TrackHands.java中的值转换为另一个线程。
尝试创建对象并将值作为参数传递,但我的程序将不会在run()
方法中使用这些新值。
答案 0 :(得分:2)
要从TrackHands
获取值,请使用get
方法访问run()
中设置的实例变量
class TrackHands {
Object output;
public void run() {
while(true) {
output = new Object();
}
}
public Object getOutput() {
return output;
}
}
将TrackHands
传递到您的使用者对象,并使用它来调用get getOutput()
方法。
传递值有点棘手,因为您可能会导致race condition。试试这样的事情
class TrackHands {
Object input = null;
public boolean setInput(Object input) {
if(this.input == null) {
this.input = input;
return true;
} else {
return false;
}
}
}
当run()
方法使用input
时,将其设置为null,以便另一个线程可以传入另一个输入。您的生产者线程将使用此循环传入输入:
public void sendInput(TrackHands th, Object input) {
boolean done = false;
while(!done) {
done = th.setInput(input);
}
}
这将继续尝试传递input
直到成功。
setInput
使用synchronized
关键字,这样只有一个线程可以同时调用此方法,否则您将获得竞争条件。
答案 1 :(得分:0)
我的一个朋友解决了我的问题。
我要感谢大家帮助我!
<强> Main.java 强>
/**
* This is the main class, it is used to start the program. The only use of this
* is to make everything more organized.
*/
package Kinect;
//import processing.core.PApplet;
/**
* @author Tony Nguyen <Tony.Nguyen@HvA.nl>
*
*/
public class Main
{
public static void main(String _args[])
{
// PApplet.main(new String[]
// {
// Sensor.class.getName()
// });
ValueStore valueStore = new ValueStore(); // ADDED THIS LINE
Thread trackHands = new Thread(new TrackHands(valueStore)); // ADDED THIS LINE
trackHands.start();
}
}
TrackHands.java
/*
* This uses the normal Java layout to track the user and prints out the coordinates of the left and right hand
*/
package Kinect;
import SimpleOpenNI.*;
import processing.core.PApplet;
import processing.core.PVector;
/**
* @author Tony Nguyen <Tony.Nguyen@HvA.nl>
* @version 1.0
*/
public class TrackHands extends PApplet implements Runnable
{
private int handLeftX, handLeftY, handRightX, handRightY = 0; // Holds the coordinates of the left hand
SimpleOpenNI kinect = new SimpleOpenNI(this); // kinect object
private ValueStore valuesStore; // ADDED THIS LINE
/**
* Constructor Takes no parameters
*/
public TrackHands()
{
}
public TrackHands(ValueStore valuesStore)
{
this.valuesStore = valuesStore;
}
/**
* run This will be executed when the thread starts
*/
@Override
public void run()
{
IntVector userList = new IntVector(); // Make a vector of ints to store the list of users
PVector leftHand = new PVector(); // Make a vector to store the left hand
PVector rightHand = new PVector(); // Make a vector to store the right hand
PVector convertedLeftHand = new PVector(); // Make a vector to store the actual left hand
PVector convertedRightHand = new PVector(); // Make a vector to store the actual right hand
kinect.enableDepth();
kinect.enableUser(SimpleOpenNI.SKEL_PROFILE_ALL);
kinect.setMirror(true);
while (true)
{
kinect.update();
kinect.getUsers(userList); // Write the list of detected users into the vector
if (userList.size() > 0) // Checks if a user is found
{
int userId = userList.get(0); // Get first user
if (kinect.isTrackingSkeleton(userId)) // If successfully calibrated
{
kinect.getJointPositionSkeleton(userId,
SimpleOpenNI.SKEL_LEFT_HAND, leftHand); // Put the position of the left hand into that vector
kinect.getJointPositionSkeleton(userId,
SimpleOpenNI.SKEL_RIGHT_HAND, rightHand); // Put the position of the left hand into that vector
kinect.convertRealWorldToProjective(leftHand,
convertedLeftHand);
kinect.convertRealWorldToProjective(rightHand,
convertedRightHand);
this.handLeftX = round(convertedLeftHand.x);
this.handLeftY = round(convertedLeftHand.y);
this.handRightX = round(convertedRightHand.x);
this.handRightY = round(convertedRightHand.y);
valuesStore.setHandValues(handLeftX, handLeftY, handRightX, handRightY); // ADDED THIS LINE
}
}
}
}
// User-tracking callbacks!
public void onNewUser(int userId)
{
System.out.println("Start pose detection");
kinect.startPoseDetection("Psi", userId);
}
public void onEndCalibration(int userId, boolean successful)
{
if (successful)
{
System.out.println(" User calibrated !!!");
kinect.startTrackingSkeleton(userId);
} else
{
System.out.println(" Failed to calibrate user !!!");
kinect.startPoseDetection("Psi", userId);
}
}
public void onStartPose(String pose, int userId)
{
System.out.println("Started pose for user");
kinect.stopPoseDetection(userId);
kinect.requestCalibrationSkeleton(userId, true);
}
}
然后添加了一个类来存储值,以便另一个类可以访问它。
<强> ValueStore.java 强>
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package Kinect;
/**
*
* @author Tony Nguyen <Tony.Nguyen@HvA.nl>
*/
public class ValueStore
{
private int leftX, leftY, rightX, rightY = 0;
public void setHandValues(int leftX, int leftY, int rightX, int rightY)
{
this.leftX = leftX;
this.leftY = leftY;
this.rightX = rightX;
this.rightY = rightY;
}
public int getLeftX()
{
return this.leftX;
}
}