簡體   English   中英

java.awt.Robot線程無法停止/銷毀?

[英]java.awt.Robot thread can't be stopped/destroyed?

我使用java.awt.Robot制作了桌面遠程控制應用程序,並且工作正常。 應用程序集成在另一個應用程序系統中,所以我希望能夠從外部系統啟動/停止遠程控制,我發現了奇怪的問題 - 我無法阻止機器人。

我嘗試了幾件事:在線程內運行它(所以我可以停止線程),使機器人對象為null而不是調用System.gc(),但問題不在於引用它的機器人線程仍在運行(在所有其他線程被銷毀之后) )。 在調試中,我可以看到正在運行的線程:守護程序線程[AWT-Windows](正在運行)。

這是代碼,將重現我的問題:

public class RobotDestroy {

  public static void main(String[] args) {

    try {
        Robot r = new Robot();
    } catch (AWTException e) {
        e.printStackTrace();
    }

    }

}

有沒有人見過類似的東西? 有解決方案嗎

謝謝

編輯:

以下是在可以停止但Robot實例仍在運行的線程中運行Robot的示例

public class RobotDestroy {

public static void main(String[] args) {

    RobotThread rt = new RobotThread();
    rt.start(); 

    try {
        //do some work before thread shut down
        Thread.sleep(5000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }

    rt.shutdown();          
}

private static class RobotThread extends Thread {

    public Robot robot;
    volatile boolean alive;

    public RobotThread(){
        try {
            this.robot = new Robot();
            this.alive = true;
        } catch (AWTException e) {
            e.printStackTrace();
        }
    }

    public void run(){

        while(alive){
            System.out.println("alive");
            try{
                robot.delay(5000);
                sleep(1000);

            }catch(Exception e){
                e.printStackTrace();
            }
        }           
    }

    public void shutdown(){
        this.alive = false;
        robot = null;
        System.out.println("shutdown");
    }       
}

}

編輯2

我嘗試了醫生殺手的建議,雖然這是一個很好的建議機器人線程仍在運行。 證明它的最佳方法是在創建機器人實例之前和之后打印出線程:

    Set<Thread> threadSet = Thread.getAllStackTraces().keySet();
    Thread[] threadArray = threadSet.toArray(new Thread[threadSet.size()]);

    for (int i = 0; i < threadArray.length; i++) {
        System.out.println(threadArray[i].getName());
    }

更新:經過大量的調試后我意識到問題不在java.awt.Robot類中 - 它是java.awt.Toolkit,它啟動應用程序結束后仍在運行的AWT-Window線程。 Robot對象有RobotPeer(java.awt.peer.RobotPeer),它返回:((ComponentFactory)工具包).createRobot(this,screen);

通常你會在接收遠程事件的線程的while(true)循環中放置一個標志,這樣你就會有類似while(isAlive)...讀取遠程事件......如果遠程事件斷開連接你就會離開循環和機器人不再獲得命令。

機器人只是活着,因為你的程序一直在調用它...你的停止循環

還包括在RobotThread中

import java.awt.AWTException;
import java.awt.Robot;
import java.util.LinkedList;

public class RobotDestroy {

    public static void main(String[] args) {
        //Set<Thread> threadSet = Thread.getAllStackTraces().keySet(); Thread[] threadArray = threadSet.toArray(new Thread[threadSet.size()]); for (int i = 0; i < threadArray.length; i++) { System.out.println("Init " + threadArray[i].getName()); }
        RobotThread rt = new RobotThread();
        rt.start(); 

        // Listen to the upcomming commands...and push them to the RobotThread

        rt.shutdown();          
    }

    private static class RobotThread extends Thread {

        public Robot robot;

        public RobotThread(){
            try {
                this.robot = new Robot();
            } catch (AWTException e) {
                e.printStackTrace();
            }
        }

        public void run(){
            Command currentCommand = getNextCommand();
            while(currentCommand.getType() != CommandType.KILL){
                // Process the command no sleep...
                // ...
                // ...

                currentCommand = getNextCommand();
            }

            System.out.println("DIED ");
        }

        private LinkedList<Command> commands = new LinkedList<Command>();

        enum CommandType {
            KILL,
            DO_SOMETHING
        }

        private synchronized Command getNextCommand() {
            while(commands.isEmpty()) {
                try {
                    System.out.println("WAITING");
                    wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            return commands.removeFirst();
        }

        public synchronized void pushCommand(Command comm) {
            commands.addLast(comm);
            notify();
        }

        public synchronized void shutdown(){
            commands.clear();
            pushCommand(new Command(CommandType.KILL));
            System.out.println("shutdown");
            //Set<Thread> threadSet = Thread.getAllStackTraces().keySet(); Thread[] threadArray = threadSet.toArray(new Thread[threadSet.size()]); for (int i = 0; i < threadArray.length; i++) { System.out.println("End " + threadArray[i].getName()); }
        }  

        class Command {
            private CommandType cmdType;
            public Command(CommandType type) {
                this.cmdType = type;
            }
            public CommandType getType() { return cmdType; }
        }
    }
}

暫無
暫無

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

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