Java多线程问题:如果我没有';t让system.in.read()捕获器立即启动和停止,即使不调用stop

Java多线程问题:如果我没有';t让system.in.read()捕获器立即启动和停止,即使不调用stop,java,multithreading,javafx,Java,Multithreading,Javafx,我试图理解线程在java中是如何工作的。我有一个javafx项目,它是一个简单的游戏界面,有问题和用户。我正试图用视频捕捉每个游戏环节的视觉信息。问题是我必须使用多线程,因为我不能同时运行gui和capturer。我有一个扩展线程的类,如下所示: 编辑: startTestButton = new Button("START"); startTestButton.addEventHandler(ActionEvent.ACTION, (e) -> { n

我试图理解线程在java中是如何工作的。我有一个javafx项目,它是一个简单的游戏界面,有问题和用户。我正试图用视频捕捉每个游戏环节的视觉信息。问题是我必须使用多线程,因为我不能同时运行gui和capturer。我有一个扩展线程的类,如下所示:

编辑:

    startTestButton = new Button("START");
    startTestButton.addEventHandler(ActionEvent.ACTION, (e) -> {


        new Thread(new Runnable() {
            @Override public void run() {

                  VideoCapture videoCapture = VideoCapture.create(VideoFormat.WMV);

                  List<VideoSource> availableVideoSources = VideoSource.getAvailable();
                  System.out.println("availableVideoSources = " + availableVideoSources);

                  if (availableVideoSources.isEmpty()) {
                      throw new IllegalStateException("No external video sources available");
                  }
                  VideoSource webCamera = availableVideoSources.get(0);
                  System.out.println("webCamera = " + webCamera);

                  videoCapture.setVideoSource(webCamera);

                  java.util.List<Codec> videoCodecs = videoCapture.getVideoCodecs();
                  System.out.println("videoCodecs = " + videoCodecs);
                  if (videoCodecs.isEmpty()) {
                      throw new IllegalStateException("No video codecs available");
                  }

                  Codec videoCodec = videoCodecs.get(2);
                  System.out.println("videoCodec = " + videoCodec);

                  EncodingParameters encodingParameters = new EncodingParameters(new File("file.wmv"));
                  encodingParameters.setBitrate(500000);
                  encodingParameters.setFramerate(10);
                  encodingParameters.setKeyFrameInterval(1);
                  encodingParameters.setCodec(videoCodec);

                  videoCapture.setEncodingParameters(encodingParameters);
                  videoCapture.start();

                  try {
                    System.in.read();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }).start();
        });
startTestButton=新按钮(“开始”);
startTestButton.addEventHandler(ActionEvent.ACTION,(e)->{
新线程(newrunnable()){
@重写公共无效运行(){
VideoCapture VideoCapture=VideoCapture.create(VideoFormat.WMV);
List availableVideoSources=VideoSource.getAvailable();
System.out.println(“availableVideoSources=“+availableVideoSources”);
if(availableVideoSources.isEmpty()){
抛出新的IllegalStateException(“没有可用的外部视频源”);
}
VideoSource网络摄像机=availableVideoSources.get(0);
System.out.println(“webCamera=“+webCamera”);
videoCapture.setVideoSource(网络摄像机);
java.util.List videoCodecs=videoCapture.getVideoCodecs();
System.out.println(“videoCodecs=“+videoCodecs”);
if(videoCodecs.isEmpty()){
抛出新的IllegalStateException(“没有可用的视频编解码器”);
}
Codec videoCodec=videoCodecs.get(2);
System.out.println(“videoCodec=“+videoCodec”);
EncodingParameters EncodingParameters=新的编码参数(新文件(“File.wmv”));
编码参数.setBitrate(500000);
编码参数。设置帧率(10);
encodingParameters.setKeyFrameInterval(1);
编码参数。设置编解码器(视频编解码器);
videoCapture.setEncodingParameters(编码参数);
videoCapture.start();
试一试{
System.in.read();
}捕获(IOE异常){
//TODO自动生成的捕捉块
e、 printStackTrace();
}
}
}).start();
});

我的线程问题是,如果我没有system.in.read()捕获程序,即使不调用stop,捕获程序也会立即启动和停止

我不使用JXCapture,但根据文档,方法
VideoCapture.start()
异步启动捕获。因此,根本没有明显的理由创建自己的背景线程。只需使用“开始”按钮启动捕获,然后使用“停止”按钮停止捕获:

private VideoCapture videoCapture = null ;

private Button startTestButton ;
private Button stopTestButton ;

// ...
startTestButton = new Button("START");
startTestButton.addEventHandler(ActionEvent.ACTION, (e) -> {


    if (videoCapture == null) {

      videoCapture = VideoCapture.create(VideoFormat.WMV);

      List<VideoSource> availableVideoSources = VideoSource.getAvailable();
      System.out.println("availableVideoSources = " + availableVideoSources);

      if (availableVideoSources.isEmpty()) {
          throw new IllegalStateException("No external video sources available");
      }
      VideoSource webCamera = availableVideoSources.get(0);
      System.out.println("webCamera = " + webCamera);

      videoCapture.setVideoSource(webCamera);

      java.util.List<Codec> videoCodecs = videoCapture.getVideoCodecs();
      System.out.println("videoCodecs = " + videoCodecs);
      if (videoCodecs.isEmpty()) {
          throw new IllegalStateException("No video codecs available");
      }

      Codec videoCodec = videoCodecs.get(2);
      System.out.println("videoCodec = " + videoCodec);

      EncodingParameters encodingParameters = new EncodingParameters(new File("file.wmv"));
      encodingParameters.setBitrate(500000);
      encodingParameters.setFramerate(10);
      encodingParameters.setKeyFrameInterval(1);
      encodingParameters.setCodec(videoCodec);

      videoCapture.setEncodingParameters(encodingParameters);
      videoCapture.start();

      startTestButton.setDisable(true);
      stopTestButton.setDisable(false);

    } else {

      throw new IllegalStateException("Capture already in progress");
    }

});

stopTestButton = new Button("Stop");
stopTestButton.setDisable(true);

stopTestButton.addEventHandler(ActionEvent.ACTION, e -> {
    if (videoCapture != null) {
        videoCapture.stop();
        videoCapture = null ;
        startTestButton.setDisable(false);
        stopTestButton.setDisable(true);
    } else {
        throw new IllegalStateException("No capture in progress");
    }
});
private VideoCapture VideoCapture=null;
私人按钮开始按钮;
私有按钮stopTestButton;
// ...
开始按钮=新按钮(“开始”);
startTestButton.addEventHandler(ActionEvent.ACTION,(e)->{
if(videoCapture==null){
videoCapture=videoCapture.create(VideoFormat.WMV);
List availableVideoSources=VideoSource.getAvailable();
System.out.println(“availableVideoSources=“+availableVideoSources”);
if(availableVideoSources.isEmpty()){
抛出新的IllegalStateException(“没有可用的外部视频源”);
}
VideoSource网络摄像机=availableVideoSources.get(0);
System.out.println(“webCamera=“+webCamera”);
videoCapture.setVideoSource(网络摄像机);
java.util.List videoCodecs=videoCapture.getVideoCodecs();
System.out.println(“videoCodecs=“+videoCodecs”);
if(videoCodecs.isEmpty()){
抛出新的IllegalStateException(“没有可用的视频编解码器”);
}
Codec videoCodec=videoCodecs.get(2);
System.out.println(“videoCodec=“+videoCodec”);
EncodingParameters EncodingParameters=新的编码参数(新文件(“File.wmv”));
编码参数.setBitrate(500000);
编码参数。设置帧率(10);
encodingParameters.setKeyFrameInterval(1);
编码参数。设置编解码器(视频编解码器);
videoCapture.setEncodingParameters(编码参数);
videoCapture.start();
startTestButton.setDisable(真);
stopTestButton.setDisable(假);
}否则{
抛出新的非法状态异常(“捕获已在进行”);
}
});
stopTestButton=新按钮(“停止”);
stopTestButton.setDisable(真);
stopTestButton.addEventHandler(ActionEvent.ACTION,e->{
如果(视频捕获!=null){
videoCapture.stop();
视频捕获=空;
startTestButton.setDisable(false);
stopTestButton.setDisable(真);
}否则{
抛出新的非法状态异常(“无捕获进行中”);
}
});

同样,由于我没有访问此库的权限,这是未经测试的,但它应该可以工作。

您看过吗?我尝试使用javafx并发的方法。扩展线程时,您需要将代码放在run()方法中,而不是start()。若您不需要改变特定于线程的行为,那个么最好实现Runnable接口并使用它来启动新线程。我不知道jxcapture,但我玩了一些JavaCV库和网络摄像头捕获,你可以看到一些例子,为什么你需要一个线程?声明
start()
异步启动捕获(即该方法立即退出,捕获可能已经在另一个线程中运行)。@whitesite我更喜欢jxcapture,因为它似乎是一个更轻松的解决方案,更容易理解,而且似乎可以工作。“James_D”似乎错误与多线程无关。但是,我还是遇到了与System.in.read()相同的问题,如果没有这一行,我的捕获会立即启动和停止