簡體   English   中英

當我想要線程時,線程不會停止嗎? (JAVA)

[英]Thread won't stop when I want it to? (Java)

我的屏幕錄制應用程序中有一個線程無法配合:

package recorder;

import java.awt.AWTException;
import java.awt.Insets;
import java.io.IOException;

import javax.swing.JFrame;

public class RepeatThread extends Thread {
    volatile boolean stop;
    public volatile Thread recordingThread;
    JFrame frame;
    int count = 0;

    RepeatThread( JFrame myFrame ) {
        stop = false;
        frame = myFrame;
    }

    public void run() {
        while( stop == false ) {
            int loopDelay = 33; // 33 is approx. 1000/30, or 30 fps
            long loopStartTime = System.currentTimeMillis();
            Insets insets = frame.getInsets(); // Get the shape we're recording

            try {
                ScreenRecorder.capture( frame.getX() + insets.left, 
                        frame.getY() + insets.top, frame.getWidth()
                        - ( insets.left + insets.right ), 
                        frame.getHeight() - ( insets.top + insets.bottom ) );
            }
            catch( AWTException e1 ) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
            catch( IOException e1 ) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            } // Add another picture

            long loopEndTime = System.currentTimeMillis();
            int loopTime = (int )( loopEndTime - loopStartTime );
            if( loopTime < loopDelay ) {
                try {
                    sleep( loopDelay - loopTime ); // If we have extra time,
                                                   // sleep
                }
                catch( Exception e ) {
                } // If something interrupts it, I don't give a crap; just
                  // ignore it
            }
        }

    }

    public void endThread() {
        stop = true;
        count = 0;
        ScreenRecorder.reset();
        // Once I get this annoying thread to work, I have to make the pictures
        // into a video here!
    }
}

多年來一直困擾着我。 它會定期將屏幕截圖帶到指定區域。

當您開始錄制時,它會隱藏(縮小)窗口。 在Mac上,當您以應用程序為焦點時,所有隱藏的窗口都會激活。 在我的類WListener (已確認可以正常工作)中,我具有:

public void windowActivated(WindowEvent e) {
        if(ScreenRecorder.recordingThread != null) {
            ScreenRecorder.recordingThread.endThread();
        }
    }

因此,應該發生的是,當他單擊應用程序時,截屏線程將停止。 但是,我必須殘酷地擰緊某些東西,因為當線程運行時,它甚至不會讓窗口重新出現。 這是我的第一個話題,所以我預料到這樣一個奇怪的問題。 你知道怎么了嗎

編輯:好的,我使stop變得不穩定,這是我制作線程的地方:

package recorder;

import java.awt.AWTException;
import java.awt.Robot;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.io.*;
import javax.imageio.ImageIO;
import javax.swing.JFrame;

public class ScreenRecorder {

    static RepeatThread recordingThread;
    static int count;

    public static void record(JFrame frame) {

        if(recordingThread == null) { //Make a new thread if we don't have one
            recordingThread = new RepeatThread(frame);
            recordingThread.start();
        }
    }

    public static void capture(int x, int y, int width, int height) throws AWTException, IOException {
        // capture the whole screen
        //BufferedImage screencapture = new Robot().createScreenCapture(
        //      new Rectangle(Toolkit.getDefaultToolkit().getScreenSize()) );

        BufferedImage screencapture = new Robot().createScreenCapture(
                new Rectangle( x, y, width, height));

        // Save as JPEG
        File directory = new File("/Users/stuart/Movies/temp");
        if(directory.exists() == false) {
            directory.mkdirs();
        }

        count ++;
        File file = new File("/Users/stuart/Movies/temp/screencapture" + count + ".jpg");
        ImageIO.write(screencapture, "jpg", file);


        // Save as PNG
        // File file = new File("screencapture.png");
        // ImageIO.write(screencapture, "png", file);

    }

    public static void stop() {

    }

    public static void reset() {
        count = 0;
    }
}

因為您顯然試圖每X毫秒執行一個工作單元,所以如果使用Java的Executor,這將容易得多:

ScheduledExecutorService service = executors.newSingleThreadScheduledExecutor();
service.scheduleAtFixedRate(new Runnable() {
  public void run() {
    // do one iteration of your work
    ScreenRecorder.capture(...);
    ...
  }
}, 0L, 33L, TimeUnit.MILLISECONDS);

...
service.shutdown(); // to stop

使用Thread手動執行此操作並沒有像創建時那樣凌亂(不是在煩您,只是說在Java中並不那么糟糕),但是到目前為止,這仍然是最簡單的選擇。

您需要使stop成為volatile ,以便您的線程可以拾取來自另一個線程的更改。

這樣可以修復1個錯誤,但是還有一些其他與線程相關的錯誤。 您應該在實踐中閱讀Java並發。 您需要使用揮發性和使用線程處理時的同步

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM