问题描述
问题是,有可能有一个外部线程,或者他们必须是他们内部运行的类。如果有人可以告诉我如何。 (外部线程)
线程,或者更准确地说,执行是一件事,线程
是紧密相关但不同的,似乎你正在混合这两个概念。
您可以将执行线程视为将按顺序执行操作的机器。定义和运行这样一个机器的一种方法是用 main()
方法写一个类 MyClass
code> java MyClass 。
另一种方法是创建 Thread
类并调用其方法 start()
。这将创建一个新的执行线程,它将运行 Thread中
类,默认情况下不做任何操作。为了使这有用,你通常覆盖 run()
方法中的代码 run
方法,这是我认为你调用一个线程内部的类... :
类MyThread extends Thread {
@Override public void run(){
// .. 。一些代码...
}
}
// ...
final Thread t = new MyThread();
t.start();
在此示例中,在 run()
方法 MyThread
返回与 MyThread
的实例相关联的执行线程 >将终止(就像当你的单线程程序从 main()
方法返回或到达结束时)。
另一种可能性是传递 Thread
一个 Runnable
的实例。然后你分离了两个概念: 线程,由 Thread
的一个实例表示,将执行 Runnable
:
class MyRunnable implements Runnable {
@Override public void run {
//这段代码将被线程执行
}
}
// ...
final MyRunnable r = new MyRunnable();
final Thread t = new Thread(t);
t.start();
这可能更接近于您所谓的外线程,虽然这个命名是非常不常见的。
因此,您会发现这里有两个不同的,但密切相关的概念。
现在,在Java中你有一种方法来创建一个执行线程,它将等待你给它一些代码来执行。创建后,它会转到池,并位于那里。您可以 提交一些代码,让它运行,当它完成后,而不是终止,执行线程保持活跃,并回到 pool 。也许这是你正在寻找的。 p>
要做到这一点,你通常使用 ExecutorService
。例如:
class MyMainClass {
private static final ExecutorService es = Executors.newFixedThreadPool(10);
private static void main(String ... args){
es.submit(new MyRunnable());
es.submit(new MyRunnable());
es.submit(new MyRunnable());
es.submit(new MyRunnable());
es.submit(new MyRunnable());
}
}
在此示例中, em>包含10个执行线程。你可以提交任何数量的 Runnable
的实例,它会分布在10个线程中。对 ExecutorService
的提交(...)
的每次调用返回 Future
,您可以使用它来了解执行线程是否已经完成, Runnable
已成功完成或由于未捕获的异常。
我建议你看一下我在这里提到的所有类的javadoc: Thread
, Runnable
, ExecutorService
, Executors
和未来
。
最后要记住的是,如果你开始使用线程和 ExecutorService
s,你会得到各种头痛。你必须考虑执行不能继续的情况(死锁,活锁),关于需要是原子的操作(即,从不同线程增加一个变量),内存可见性(即,如果你改变一个字段的值没有照顾,可能发生其他线程永远不会注意到该字段的更改!)。还要记住,JVM不会死,直到每个最后的非守护进程线程完成;换句话说,上面的例子永远不会终止,即使所有提交的 Runnable
完成,因为<$ c 在 ExecutorService
仍然有效!
The question is, is it possible to have an external thread or do they have to be internal to the class they run in. If so could someone show me how. (external thread)
A thread, or, more precisely, a thread of execution is something, and the class Thread
is something closely related but different, and it seems that you are mixing up these two concepts.
You can think of a thread of execution as a machine that will execute operations sequentially. One way to define and run such a machine is to write a class MyClass
with a main()
method and call java MyClass
.
Another way is to create a new instance of the Thread
class and call its method start()
. This will create a new thread of execution which will run the code that is in the run()
method of the Thread
class, which does nothing by default. For this to be useful, you usually override the run
method, which is what I think you are calling a thread internal to the class...:
class MyThread extends Thread {
@Override public void run() {
// ... some code ...
}
}
// ...
final Thread t = new MyThread();
t.start();
In this example, after the run()
method of the class MyThread
returns, the thread of execution associated to that instance of MyThread
will terminate (just like when your single-threaded program returns from -- or reaches the end of -- your main()
method).
Another possibility is to pass the Thread
an instance of a Runnable
. Then you separate the 2 concepts: the thread of execution, which is represented by an instance of Thread
, will execute the code in the instance of Runnable
:
class MyRunnable implements Runnable {
@Override public void run {
// this code will get executed by a thread
}
}
// ...
final MyRunnable r = new MyRunnable();
final Thread t = new Thread(t);
t.start();
This maybe closer to what you call an external thread, although this nomenclature is highly unconventional.
So, you see that there are 2 different, but closely related, concepts here.
Now, in Java you have a way to create a thread of execution that will be waiting for you to give it some code to execute. After it is created, it goes to a pool, and sits there. You submit some code for it to run, and when it finishes, instead of terminating, the thread of execution keeps alive and goes back to that pool. Maybe this is what you are looking for.
To do it, you usually use an ExecutorService
. For example:
class MyMainClass {
private static final ExecutorService es = Executors.newFixedThreadPool(10);
public static void main(String... args) {
es.submit(new MyRunnable());
es.submit(new MyRunnable());
es.submit(new MyRunnable());
es.submit(new MyRunnable());
es.submit(new MyRunnable());
}
}
In this example, the pool contains 10 threads of execution. You can submit any amount of instances of Runnable
for it, and it will distribute them among the 10 threads. Each call to submit(...)
on the ExecutorService
returns an instance of Future
, which you can use to know if the thread of execution that was running your Runnable
did already finish, and if it finished successfully or due to an uncaught exception.
I suggest that you take a look at the javadocs for all the classes I mentioned here: Thread
, Runnable
, ExecutorService
, Executors
and Future
. There's a lot to learn from that documentation!
As a final note, remember that if you start playing with threads and ExecutorService
s, you will get all kinds of headache. You will have to think about situations in which the execution cannot proceed (deadlocks, livelocks), about operations that need to be atomic (ie, incrementing a variable from different threads), memory visibility (ie, if you change the value of a field without "taking care", it can happen that other threads will never notice the change to that field!). Also remember that the JVM won't die until every last non-daemon thread finishes; in other words, the example above will never terminate, even if all the submitted Runnable
s finish, because the threads of execution in the ExecutorService
are still alive!
这篇关于java外部线程(使用的类文件外部)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!