我已经创建了java Thread的示例程序,其中我使用stop()方法使用以下程序停止线程
public class App extends Thread
{
Thread th;
App(String threadName)
{
th = new Thread(threadName);
}
public synchronized void run() // Remove synchronized
{
for (int i = 0; i < 5; i++) {
System.out.println(th.getName()+" "+i);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
}
}
}
public static void main( String[] args )
{
App thread_1 = new App("Thread-1");
thread_1.start();
thread_1.setPriority(MAX_PRIORITY); //Comment this
thread_1.stop();
App thread_2 = new App("Thread-2");
thread_2.start();
}
}
上述程序的输出是:
Thread-1 0
Thread-1 1
Thread-1 2
Thread-1 3
Thread-1 4
Thread-2 0
Thread-2 1
Thread-2 2
Thread-2 3
Thread-2 4
即。 thread_1没有停止。当我删除代码时同步或优先级线程立即停止并输出
Thread-2 0
Thread-2 1
Thread-2 2
Thread-2 3
Thread-2 4
我无法理解它为什么会像这样工作。
答案 0 :(得分:4)
Thread类的大多数公共方法都在Thread实例本身上同步。 http://hg.openjdk.java.net/jdk6/jdk6/jdk/file/5672a2be515a/src/share/classes/java/lang/Thread.java
您的run()方法在Thread实例上同步。 stop()方法调用stop(Throwable),它也在Thread实例上同步,其签名是:
@Deprecated
public final synchronized void stop(Throwable obj) {
当线程本身仍在您的thread_1.stop()
方法中运行时,同步会阻止主线程进入synchronized run()
。
这是为什么总是使用私有对象进行同步的明智的例子。例如,这样做......
class Foobar {
private final Object lock = new Object();
public void do_something() {
synchronized(lock) {
...
}
}
}
而不是这样做......
class Foobar {
public synchronized void do_something() {
...
}
}
第二个版本更详细(欢迎使用Java!),但它会阻止Foobar类的用户以干扰其自身作为同步对象的方式将其用作同步对象。
答案 1 :(得分:1)
Thread.stop()已弃用。考虑使用这个:
public class App extends Thread
{
Thread th;
volatile boolean bStopThread;
App(String threadName)
{
th = new Thread(threadName);
bStopThread = false;
}
public void stopThread(){
bStopThread = true;
}
public synchronized void run() // Remove synchronized
{
for (int i = 0; i < 5; i++) {
if(bStopThread) return;
System.out.println(th.getName()+" "+i);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
}
}
}
public static void main( String[] args ) throws InterruptedException
{
App thread_1 = new App("Thread-1");
thread_1.start();
thread_1.setPriority(MAX_PRIORITY); //Comment this
thread_1.stopThread();
App thread_2 = new App("Thread-2");
thread_2.start();
}
}
虽然我没有测试过,但它应该可以正常工作。
答案 2 :(得分:0)
您的应用程序中有3个线程:主线程,运行main方法的代码,thread_1和thread_2。你的主线程在某个时间点X启动thread_1,然后在某个时间点Y,Y&gt; X调用thread_1.stop()。
现在,点X和Y之间可能发生的事情是CPU调度程序可以决定:&#34;我现在让thread_1运行&#34;。 Thread_1将获得CPU,将运行并将打印他的文本。或者,CPU调度程序可以决定:&#34;主线程现在正在运行...让它运行&#34;。而且,在调用stop之前,thread_1将不会获得CPU,并且不会打印任何内容。
因此,您无法控制CPU调度。您只能假设提高线程提示调度程序的优先级以选择上述第一个选项。
但是。不推荐使用stop,所以永远不要使用它。并且不要试图猜测多个线程的执行顺序。
答案 3 :(得分:0)
在主方法中加入try catch。打印堆栈跟踪和捕获的异常消息。在run方法中相同。然后java会告诉你问题。
MHC的方法更好,但就像我说的那样 - 有时(很少)当你无法控制线程时,只能调用stop。但是在这种情况下你可以控制它,所以MHC方法可以很好地工作。
但是我没看到你的代码有什么问题 - 它在我的笔记本电脑上运行良好,也许你没有清理并重新编译? Chane一些消息,以便您知道最新的代码正在运行
我用过:
package academic.threads;
public class StopThHighPri extends Thread {
Thread th;
volatile boolean bStopThread;
StopThHighPri(String threadName) {
th = new Thread(threadName);
bStopThread = false;
}
public void stopThread(Thread t) {
//bStopThread = true;
try {
t.stop();
} catch (Throwable e) {
System.err.println(" Stop th " + e + " " + e.getMessage());
}
}
public synchronized void run() // Remove synchronized
{
try {
for (int i = 0; i < 5; i++) {
if (bStopThread)
return;
System.out.println(th.getName() + " " + i);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
}
}
} catch (Exception e) {
e.printStackTrace();
System.out.println("run err " + e);
}
}
public static void main(String[] args) {
try {
System.err.println("Code version 002");
StopThHighPri thread_1 = new StopThHighPri("Thread-1");
thread_1.start();
thread_1.setPriority(MAX_PRIORITY); // Comment this
thread_1.stopThread(thread_1);
StopThHighPri thread_2 = new StopThHighPri("Thread-2");
thread_2.start();
} catch (Exception e) {
e.printStackTrace();
System.out.println("MNain err " + e);
}
}
}
输入类似System.err.println(“Code version 002”);
的内容并更改002,003。因此,每次编辑课程时,您都知道最新代码正在运行。再次学习这是可以的,但不需要在这里停止