从辅助线程在主线程上运行代码?

这是一个普通的Java问题,而不是Android首先关闭的问题!

我想知道如何在主线程上运行代码,从辅助线程的上下文。 例如:

new Thread(new Runnable() { public void run() { //work out pi to 1,000 DP (takes a while!) //print the result on the main thread } }).start(); 

那种事情 – 我意识到我的例子有点差,因为在Java中你不需要在主线程中打印出来的东西,而且Swing也有一个事件队列 – 但是你可能需要的通用情况在后台线程的上下文中,在主线程上运行说一个Runnable。

编辑:为了比较 – 这是我在Objective-C中如何做到这一点:

 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0UL), ^{ //do background thread stuff dispatch_async(dispatch_get_main_queue(), ^{ //update UI }); }); 

提前致谢!

没有通用的方法可以将一些代码发送到另一个正在运行的线程并说“嘿,你,这样做”。 您需要将主线程置于一个状态,在该状态下它具有接收工作的机制并等待工作。

这是一个简单的例子,设置主线程等待从其他线程接收工作并在它到达时运行它。 显然你想要添加一种实际结束程序的方法等等……!

 public static final BlockingQueue queue = new LinkedBlockingQueue(); public static void main(String[] args) throws Exception { new Thread(new Runnable(){ @Override public void run() { final int result; result = 2+3; queue.add(new Runnable(){ @Override public void run() { System.out.println(result); } }); } }).start(); while(true) { queue.take().run(); } } 

如果你在Android上,使用Handler应该可以胜任吗?

 new Handler(Looper.getMainLooper()).post(new Runnable () { @Override public void run () { ... } }); 

一个旧的讨论,但如果是向主线程发送请求(不是相反的方向)的问题,你也可以用期货来做。 基本目标是在后台执行某些操作,并在完成后获取结果:

 public static void main(String[] args) throws InterruptedException, ExecutionException { // create the task to execute System.out.println("Main: Run thread"); FutureTask task = new FutureTask( new Callable() { @Override public Integer call() throws Exception { // indicate the beginning of the thread System.out.println("Thread: Start"); // decide a timeout between 1 and 5s int timeout = 1000 + new Random().nextInt(4000); // wait the timeout Thread.sleep(timeout); // indicate the end of the thread System.out.println("Thread: Stop after " + timeout + "ms"); // return the result of the background execution return timeout; } }); new Thread(task).start(); // here the thread is running in background // during this time we do something else System.out.println("Main: Start to work on other things..."); Thread.sleep(2000); System.out.println("Main: I have done plenty of stuff, but now I need the result of my function!"); // wait for the thread to finish if necessary and retrieve the result. Integer result = task.get(); // now we can go ahead and use the result System.out.println("Main: Thread has returned " + result); // you can also check task.isDone() before to call task.get() to know // if it is finished and do somethings else if it is not the case. } 

如果您的目的是在后台执行多项操作并检索结果,您可以如上所述设置一些队列,或者您可以在多个期货中拆分该流程(一次开始或在需要时开始新的,甚至从另一个未来开始) 。 如果将每个任务存储在地图或列表中,并在主线程中初始化,您可以随时检查所需的期货,并在完成后获得结果。

您可能希望使用“偶数调度线程”,其中大多数事件驱动的事情发生。 如果你正在使用swing,那么:

  SwingUtilities.invokeLater(new Runnable() { public void run() { Your code here. } }); 

或者创建一个实现Runnable的类并将其传递给invokeLater()。

如果您正在使用我强烈推荐的JavaFX,那么您可以使用

  Platform.runLater(new Runnable() { @Override public void run() { alert(text); } }); 

从你的非UI线程中,runnable将从你的线程返回的UI线程执行。