有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java在线程启动之前获取线程ID

我有一个配对机制的想法,它通过线程ID识别客户机。当线程被销毁时,客户端的配对将被销毁,其ID设置为-1

现在,为了获得线程ID,线程当然必须已经运行或启动

我想知道我是否可以创建一个线程,获取ID,然后在以后设置runnable,或者是否可以获取正在运行我的函数的当前线程的ID

我想做的示例:

void createClientThreaded(final Client client) {
    new Thread(new Runnable() {
        @Override public void run() {
            while(!client.stop()) {
                Utils.sleep(1000);
                //Do other stuff here..

                client.setThreadID(/* This Thread's ID */);

                // Do other stuff here..
            }
        }
    });
}

有什么办法可以做到这一点吗?线程ID是每个进程唯一的还是整个系统唯一的?换句话说,两个同时运行的jar文件是否具有相同的线程ID


共 (2) 个答案

  1. # 1 楼答案

    线程id是不可变的,因此当线程终止时,不能将其设置为-1

    创建线程时会立即创建id,而不是线程启动时会立即创建id,因此您可以创建线程,读取其id,然后稍后再启动它

    然而,如果您要创建和销毁大量线程,那么您将招致很高的运行时成本。使用ThreadPoolExecutor来执行您的Runnable会更有效,但是这排除了创建线程、读取其id以及稍后启动线程的选项。另一个选项是创建自己的类,该类使用可变id实现Runnable

    class MyRunnable implements Runnable {
        private static AtomicLong idCounter = new AtomicLong(0);
        private long id;
    
        public MyRunnable() { this.id = idCounter.getAndIncrement(); }
    
        public void setId(long id) { this.id = id; }
        public long getId() { return this.id; }
        public void run() {}
    }
    

    线程ID是每个进程的,而不是系统范围的。此外,进程可以重用线程id(例如,如果id=5的线程终止,则进程可以将id=5分配给新线程)

  2. # 2 楼答案

    要稍后运行runnable,请执行以下操作:

    import java.util.concurrent.Semaphore;
    
    public class Main {
        public static void main(String[] args) {
            DelayedExecutionThread blocker = new DelayedExecutionThread();
            Thread t = blocker.getThread();
            t.start();
    
            System.out.println("Thread Started..");
            sleep(3000);
            System.out.println("Executing..");
    
            blocker.setRunnable(new Runnable() {
                @Override
                public void run() {
                    System.out.println("RAN THE THREAD LATER");
                }
            });
    
            sleep(1);
            System.out.println("Executed..");
        }
    
        private static class DelayedExecutionThread {
            private Semaphore lock = new Semaphore(1, true);
            private Thread thread;
            private Runnable target;
    
            public DelayedExecutionThread() {
                this.lock.acquireUninterruptibly();
    
                this.thread = new Thread(new Runnable() {
                    @Override
                    public void run() {
                        DelayedExecutionThread.this.lock.acquireUninterruptibly();
                        DelayedExecutionThread.this.lock.release();
                        DelayedExecutionThread.this.lock = null;
    
                        if (DelayedExecutionThread.this.target != null) {
                            DelayedExecutionThread.this.target.run();
                        }
                    }
                });
            }
    
            public Thread getThread() {
                return this.thread;
            }
    
            public void setRunnable(Runnable runnable) {
                this.lock.release();
                this.target = runnable;
            }
        }
    
        private static void sleep(long millis) {
            try {
                Thread.sleep(millis);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    

    我用了一个信号灯。您只需要某种类型的锁定或条件。当线程启动时,它会尝试获取锁,这会导致它“等待”直到可以获取它。当您在稍后的某个时间点设置runnable时,它将释放锁,导致线程获取它,释放它,然后继续执行