我只想在按下返回键时启动并停止线程。 这里线程停止正常,但我不能再次启动该线程请帮助。 还解释了我使用volatile关键字。这对我来说是有帮助的。
public class Sync extends Thread{
public boolean meth= true;
public void run(){
while(meth){
System.out.println("hello");
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
}
}
}
public void shutdown(){
meth=false;
}
public void startup(){
meth=true;
}
}
MAIN CLASS``
package com.Sync;
import java.util.Scanner;
public class SyncMain {
public static void main(String[] arg) throws InterruptedException{
Sync hi= new Sync();
hi.start();
System.out.println("press enter to stop");
Scanner d= new Scanner(System.in);
d.nextLine();
hi.shutdown();
System.out.println("press enter to start");
d.nextLine();
hi.startup();
}
}
输出
run:
press enter to stop
hello
hello
hello
hello
press enter to start
BUILD SUCCESSFUL (total time: 6 seconds)
答案 0 :(得分:2)
线程不是可重入的,也就是说,一旦它们退出run
方法,它们就无法重新启动,您需要创建一个新实例。
一个解决方案是创建Sync
的新实例并启动它,但基于您的代码可能更好的解决方案是使用wait
锁来“暂停”线程和允许它恢复,例如......
public static class Sync implements Runnable {
private AtomicBoolean keepRunning = new AtomicBoolean(true);
private AtomicBoolean pause = new AtomicBoolean(false);
private ReentrantLock lckPause = new ReentrantLock();
private Condition conPause = lckPause.newCondition();
public void run() {
while (keepRunning.get() && !Thread.currentThread().isInterrupted()) {
while (pause.get() && !Thread.currentThread().isInterrupted()) {
lckPause.lock();
try {
System.out.println("Paused");
conPause.await();
} catch (InterruptedException ex) {
ex.printStackTrace();
} finally {
lckPause.unlock();
}
}
if (!Thread.currentThread().isInterrupted()) {
System.out.println("hello");
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
}
}
}
}
public void setPaused(boolean paused) {
if (pause.get() != paused) {
pause.set(paused);
if (!paused) {
lckPause.lock();
try {
conPause.signal();
} finally {
lckPause.unlock();
}
}
}
}
public void terminate() {
keepRunning.set(false);
setPaused(false);
}
}
这基本上设置了两个循环,一个用于保持线程运行直到它“终止”,一个用于捕获“暂停”条件......
然后你可以做一些像......
public static void main(String[] args) {
Sync hi = new Sync();
Thread t = new Thread(hi);
t.start();
Scanner d = new Scanner(System.in);
System.out.println("press enter to pause");
d.nextLine();
hi.setPaused(true);
System.out.println("press enter to resume");
d.nextLine();
hi.setPaused(false);
System.out.println("press enter to terminate");
d.nextLine();
hi.terminate();
try {
t.join();
} catch (InterruptedException ex) {
ex.printStackTrace();
}
System.out.println("Has terminated");
}
简单地运行它......
您应该注意到,通常不建议直接从Thread
扩展,并且通常鼓励使用单独的Runnable
,原因有很多,但您将来发现最有用的原因是API的不同部分(例如Runnable
API)更广泛地支持Executors
,使其成为更加灵活的选项
查看Concurrency Trail了解更多详情,尤其是Lock Objects