触发器线程';Java中的另一个线程使用的方法
假设我有一个触发器线程';Java中的另一个线程使用的方法,java,multithreading,Java,Multithreading,假设我有一个类MyThread,它使用dosomething()方法实现Runnable: 如果我这样做: main(){ MyThread my = new MyThread().run(); Object o = my.dosomething(p); } dosomething是在myThread上执行还是在main线程中执行 如何在myThread上从主线程开始执行dosomething,并检索返回的对象?这是不可能的 创建线程时,它在run()中运行代码并退出。
类MyThread
,它使用dosomething()方法实现Runnable
:
如果我这样做:
main(){
MyThread my = new MyThread().run();
Object o = my.dosomething(p);
}
dosomething
是在myThread
上执行还是在main
线程中执行
如何在myThread上从主线程开始执行dosomething
,并检索返回的对象?这是不可能的
创建线程时,它在run()
中运行代码并退出。
没有办法将代码注入到不同的线程中;这将打破核心执行模型。(在一个线程中,代码按顺序运行,中间没有任何内容)
如果愿意,您可以创建一个线程来侦听队列中的回调(Runnable
instances)并执行它们(如消息循环)。
这就是UI线程的工作方式
而且,你实际上并不是在开始一条线;您需要编写新线程(someRunnable).start()
它将在主线程上执行,因为调用该方法的是该线程。如果希望dosomething
在单独的线程中运行,请在run()
中调用它,并将结果存储在myThread
字段中,以便以后检索
您可能希望检查java.util.concurrent
中的类或其他内容,以获得等待结果可用的方便方法
编辑:如果dosomething
只应运行到满足某些必须在主线程中标记的条件,则让run()
阻塞,直到主线程以某种方式向另一个线程发出可以继续的信号
编辑2:在这里,有人确认这是被问到的问题:
package threadtest;
public class Main {
public static void main(final String[] args) {
final MyThread otherThread = new MyThread();
System.out.println("Main thread: I'm gonna start the other thread now...");
otherThread.start();
System.out.println("Main thread: there, hope it does well.");
try {
Thread.sleep(1000); //Lets main thread take a snooze...
} catch(InterruptedException ex) {
//whatever
}
System.out.println("Main thread: I'm gonna do some stuff in the meantime...");
try {
Thread.sleep(200); //Lets main thread take a snooze...
} catch(InterruptedException ex) {
//whatever
}
System.out.println("Main thread: maybe clean up the kitchen.");
try {
Thread.sleep(1000); //Lets main thread take a snooze...
} catch(InterruptedException ex) {
//whatever
}
System.out.println("Main thread: does other thread have something for me yet?");
if(otherThread.getResult() == null)
System.out.println("Main thread: nope, not yet.");
try {
Thread.sleep(500); //Lets main thread take a snooze...
} catch(InterruptedException ex) {
//whatever
}
System.out.println("Main thread: oh crap! I forgot to tell it that it may execute its method!");
otherThread.allowToExecute();
System.out.println("Main thread: phew... better keep checking now before it gets angry.");
while(otherThread.getResult() == null) {
try {
Thread.sleep(100); //Lets main thread take a snooze...
} catch(InterruptedException ex) {
//whatever
}
}
System.out.println("Main thread: there we go, it gave me a result. Rest in peace, other thread...");
}
private static class MyThread extends Thread {
private boolean mayExecuteDoSomething = false;
private Object result = null;
@Override
public void run() {
System.out.println("Other thread: whoa, someone started me!");
while(!mayExecuteDoSomething) {
try {
Thread.sleep(100); //I'm gonna sleep for a bit...
} catch(InterruptedException ex) {
//whatever
}
}
System.out.println("Other thread: alright, I'm allowed to execute my method!");
result = doSomething();
System.out.println("Other thread: there, did it. I'll just call it quits now.");
}
public void allowToExecute() {
mayExecuteDoSomething = true;
}
private Object doSomething() {
return new Object();
}
public Object getResult() {
return result;
}
}
}
这是一个非常粗糙的方法来处理这个问题。不过,基本概念就在那里。在现实中,你希望使用合适的异步计算,如调用和将来的东西。< /P> < P>听起来你可能想考虑调用和期货。
在中有一个不错的解释,例如,您可以使用委托
new MyThread(callWhenFinishObject)
- 如果这样做,它将无法编译:您试图将void方法的结果,
void run()
,分配给类型为MyThread
的对象李>
- 实现runnable并调用
run()
不会导致代码在单独的线程中执行,除非您将其传递给另一个线程(即Tread t=new thread(my);
)
如何在myThread上从主线程开始执行dosomething并检索返回的对象
您可以通过将doSomething()
的结果存储在以后可以访问的位置来实现这一点
class MyClass
{
public Object doSomething()
{
// return the object
return new Object();
}
}
class MyRunnable implements Runnable
{
private final MyClass _mc;
private final object _lock;
private final List<object> _results;
public MyRunnable(MyClass mc, List<object> results, object lock)
{
_mc = mc;
_lock = lock;
_results = results;
}
public void run()
{
synchronized(_lock)
{
_results.add(_mc.doSomething());
}
}
}
class-MyClass
{
公共对象doSomething()
{
//返回对象
返回新对象();
}
}
类MyRunnable实现Runnable
{
私人最终MyClass mc;
私有最终对象_锁;
私人最终名单——结果;
公共MyRunnable(MyClass mc、列表结果、对象锁)
{
_mc=mc;
_锁=锁;
_结果=结果;
}
公开募捐
{
已同步(_锁)
{
_结果:添加(_mc.doSomething());
}
}
}
所以现在主要是:
void main(){
MyClass mc = new MyClass();
List<object> results = new List<object>();
object lock = new object();
// Execute your thread and wait for it to complete
Thread t = new Thread(new MyRunnable(mc, results, lock ));
t.start();
t.join();
// Get the results
for(object result:results)
{
// do something with the result
}
}
void main(){
MyClass mc=新的MyClass();
列表结果=新列表();
对象锁=新对象();
//执行线程并等待它完成
线程t=新线程(新MyRunnable(mc、结果、锁));
t、 start();
t、 join();
//得到结果
用于(对象结果:结果)
{
//对结果做点什么
}
}
这应该会让你知道你做错了什么。更现实的例子是,如果你产生多个线程,并发运行它们,然后加入所有线程,直到它们全部完成。@Skip,请使用正确的命名约定:类名以大写字母开头(例如,MyThread
而不是MyThread
)@G_H:是的。他要求在一个单独的已经启动的线程上运行他的方法。我想他只是想启动一个线程以异步方式执行该方法,但控制从主线程在该线程内调用该方法的确切时间。然后在该方法返回后检索该方法的结果。正如其他人指出的,还有很多这不是不可能的。仅仅因为海报的措辞可能有点混乱或者他/她不熟悉Java线程并不意味着我们不应该在字里行间阅读。@G_H:不;他想在myThread
上运行它,他认为这是一个已经开始的线程。好吧,所以他错了run()方法也是。应该使用start()。更有理由纠正他,对吗?是的;我只是注意到。Thnx,是的,使用Callables
处理返回值的线程要容易得多。
class MyClass
{
public Object doSomething()
{
// return the object
return new Object();
}
}
class MyRunnable implements Runnable
{
private final MyClass _mc;
private final object _lock;
private final List<object> _results;
public MyRunnable(MyClass mc, List<object> results, object lock)
{
_mc = mc;
_lock = lock;
_results = results;
}
public void run()
{
synchronized(_lock)
{
_results.add(_mc.doSomething());
}
}
}
void main(){
MyClass mc = new MyClass();
List<object> results = new List<object>();
object lock = new object();
// Execute your thread and wait for it to complete
Thread t = new Thread(new MyRunnable(mc, results, lock ));
t.start();
t.join();
// Get the results
for(object result:results)
{
// do something with the result
}
}