2013-04-13 3 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); 
    } 
} 

Я пробовал использовать геттер и сеттер, чтобы получить значения из TrackHands.java в другой thr Свинец. Пробовал создавать объекты и передавать значения в качестве параметров, но тогда моя программа не будет использовать эти новые значения в методе run().

+0

, если Google 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; 
    } 
} 

Pass TrackHands в свой потребительский объект и использовать его для вызова получить 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, установите его в нуль, так что другой поток может перейти в другой вход. Ваш продюсер поток будет использовать этот цикл, чтобы пройти на входе:

public void sendInput(TrackHands th, Object input) { 
    boolean done = false; 
    while(!done) { 
     done = th.setInput(input); 
    } 
} 

Это будет продолжать пытаться пройти в input, пока не удается.

setInput использует ключевое слово synchronized, так что только один поток может вызвать этот метод сразу, в противном случае вы получите условие гонки.

+0

должен использовать объекты в java.util.одновременно передавать значения между потоками – tgkprog

+0

Спасибо, ребята, за помощь! Значения, которые я хочу получить от TrackHands, часто обновляются, и мне нужны только самые новые значения (это координаты X и Y из ваших рук), поэтому блокировки на самом деле не нужны. Или вы порекомендовали мне использовать их в любом случае? Строка «Выход объекта»; на второй строке мне нужно создать объект 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; 
    } 
} 
Смежные вопросы