2016-07-14 103 views
1

我有一个java类,它实际上是从webcamer捕获帧。这个类有两种启动方式和一种停止方式。我想将这个类添加到我创建的gui中。但是,当我添加功能,因为他们是我的游戏卡住了。看来我需要在这里做一些多线程。我如何将我的类方法添加到新线程中?将java类的方法添加到一个新的线程

编辑:我的代码,现在是这样的:

Thread t2 = new Thread(new Runnable() { 
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(); 

    //System.in.read(); 
    //videoCapture.stop(); 

    }}); 

我通过调用t2.start运行这个线程(),我怎么能在第二个函数调用videoCapture.stop()?

回答

1

使用的AtomicBoolean你两者代表状态方法,并使用该状态来读取或终止流。

import java.util.concurrent.atomic.AtomicBoolean; 

public class CameraCapture { 

    private AtomicBoolean doCapture = new AtomicBoolean(); 

    public Thread startCapture() { 
     System.out.println("Setting Capture status to true"); 
     doCapture.set(true); 


     Thread capture = new Thread(new Runnable() { 
      public void run() { 
       System.out.println("Initializing Sources"); 
       /* Initialization Code here. */ 
       System.out.println("Found WebCam!"); 

       System.out.println("Configuring Codec"); 

       while(doCapture.get()) { 
        System.out.println("\tReading Data!"); 
        //Read and handle input. 
        try { 
         Thread.sleep(1000); 
        } catch (InterruptedException exception) { 
         // FIXME: minimum of logging. 
         exception.printStackTrace(); 
        } 
       } 

       System.out.println("Capture Terminated!"); 

      }}, "CameraCapture Injest"); //Name the thread! 

     System.out.println("Starting Capture");   
     capture.start(); 
     return capture; 
    } 

    public void stopCapture() { 
     System.out.println("Disabling capture"); 
     doCapture.set(false); 
    } 
} 

此测试应显示控制台中的工作流程。

@Test 
    public void captureThreadTest() throws Exception { 
     CameraCapture capture = new CameraCapture(); 
     Thread captureRunner = capture.startCapture(); 
     Thread.sleep(10000); 

     capture.stopCapture(); 

     captureRunner.join(); 
    } 

请注意,我从)返回线程参考startCapture负全部 的单元测试示例的目的(因为我需要执行 的加入(得到上次输出)。我不会建议在产品代码中公开 ,因为这不会提供良好的封装 以及该线程状态的所有权。

Setting Capture status to true 
Starting Capture 
Initializing Sources 
Found WebCam! 
Configuring Codec 
    Reading Data! 
    Reading Data! 
    Reading Data! 
    Reading Data! 
    Reading Data! 
    Reading Data! 
    Reading Data! 
    Reading Data! 
    Reading Data! 
    Reading Data! 
Disabling capture 
Capture Terminated! 
2

Runner。如果你使用Eclipse,有一个模板会自动为你编写你的跑步者。另外,如果您正在使用Swing,则应该将所有内容都放到Swing事件队列中。

如果您还没有这样做,您可能需要重新设计GUI,以便它是一个控制器而不是应用程序本身(可能的原因是,您在使用GUI时遇到了此线程问题) 。

相关的文档

Runnable文档:https://docs.oracle.com/javase/7/docs/api/java/lang/Runnable.html

EventQueue.invokeLater(Runnable)文档:http://docs.oracle.com/javase/8/docs/api/java/awt/EventQueue.html#invokeLater-java.lang.Runnable-

并发和SwingWorkerhttps://docs.oracle.com/javase/tutorial/uiswing/concurrency/worker.html

+0

我使用的是eclipse和javafx。所以我可以为我的班级创建跑步者? – konstantin

+0

使用跑步者获取新线程。然后使用该跑步者进行扫描。您可能还想研究JavaFX中的'SwingWorker'和替代方法。我记得在JavaFX中,'invokeLater'等价物是'Platform.runLater(...)'。 – ifly6

+0

我不能这样做:(我必须在javafx中工作 – konstantin