2016-07-14 60 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