java - 从另一个线程访问值

标签 java multithreading kinect simple-openni

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

我有两个 .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 <<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="61350e0f184f2f061418040f212917204f0f0d" rel="noreferrer noopener nofollow">[email protected]</a>>
 *
 */
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 <<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="53073c3d2a7d1d34262a363d131b25127d3d3f" rel="noreferrer noopener nofollow">[email protected]</a>>
 * @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() 方法中使用这些新值。

最佳答案

要从 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);
    }
}

这将继续尝试传入输入,直到成功。

setInput 使用 synchronized 关键字,以便一次只有一个线程可以调用此方法,否则您将遇到竞争条件。

关于java - 从另一个线程访问值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15990201/

相关文章:

c# - 在kinect SDK中的图像(视频)的某些部分放置白色像素

windows - kinect for windows V2.0 Developer Preview,相机工作,深度传感器不工作

java - Jetty HTTP 客户端摘要验证

java - WSO2 Eclipse Luna 数据映射器加载错误

multithreading - JNDI 名称解析在 tomee 的新线程中失败

f# - F# 中的 Kinect 骨架跟踪问题

java - 表单标签内的 ${webappRoot}

java - JSF 中基于表单的身份验证

c++ - MPI_Send 到在同一进程上运行的多个 POSIX 线程

java - ThreadPoolExecutor 关闭 API 文档措辞 "does not wait"