2013-04-13 174 views
1

我的问题是:如何从另一个线程访问值?从另一个线程访问值

我有两个.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 <[email protected]> 
* 
*/ 
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 <[email protected]> 
* @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中的值转换为另一个thr元首。 尝试创建对象并将值作为参数传递,但那么我的程序将不会在run()方法中使用这些新值。

+0

如果谷歌的java.util.concurrent教程会得到一些很好的指针http://docs.oracle.com/javase/tutorial/essential/concurrency/locksync.html您至少需要共享对象周围的同步关键字,否则可能会出现脏读 – tgkprog

回答

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使用​​关键字,因此只有一个线程可以一次调用此方法,否则您将获得竞争条件。

+0

应该使用java.util中的对象。并发传递线程间的值 – tgkprog

+0

非常感谢你们的帮助! 我想从TrackHands获得的值经常更新,我只需要最新的值(那些是手中的X和Y坐标),所以我认为锁并不是真的需要。或者你推荐我使用它们吗? 'Object output'行;'在第二行,我必须创建一个Object对象吗?或者这只是为了示范目的? 因为我真的不知道如何给对象赋值,所以我可以从另一个线程获取它。 – iKaos

+0

如果您只需要最新的输入,那么就不需要锁定,您可以使对象成为您想要的任何类型 - 这仅仅是为了演示目的。 –

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 <[email protected]> 
* 
*/ 
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 <[email protected]> 
* @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 <[email protected]> 
*/ 
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; 
    } 
} 
相关问题