我有这个配对机制的想法,通过他们的ThreadID识别客户端。当线程被销毁时,客户端的配对被破坏,其ID被设置为-1。
现在为了让我获得线程ID,线程当然必须已经运行或启动。
我想知道我是否可以创建一个线程,获取ID,然后稍后在OR上设置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?
答案 0 :(得分:3)
线程id是不可变的,因此当线程终止时,您将无法将其设置为-1。
创建线程后立即创建id,线程一启动就 not ,因此您可以创建线程,读取其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分配给新线程)。
答案 1 :(得分:1)
稍后运行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时,它将释放锁定,导致线程获取它,释放它并继续执行。