使用 java 的多线程概念控制 运行 线程
Control of running Thread using multiple threading concept of java
我只想在按下 return 键时启动和停止线程。
这里线程已停止正常,但我无法再次启动该线程,请帮忙。
还给我解释一下 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;
}
}
主要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)
线程是不可重入的,即一旦退出run
方法,就不能重新启动,需要新建一个实例。
一个解决方案是创建一个 Sync
的新实例并启动它,但根据您的代码,更好的解决方案可能是使用 wait
锁 "pause" 线程并允许它恢复,例如...
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);
}
}
这基本上设置了两个循环,一个是保持线程 运行ning 直到 "terminated",另一个是捕获 "pause" 条件...
然后你可以做类似...
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
,原因有很多,但您会发现其中一个最有用future is Runnable
在 API 的不同部分(如 Executors
API)得到更广泛的支持,使其成为一个更加灵活的选项
看看Concurrency Trail for more details, in particular Lock Objects
我只想在按下 return 键时启动和停止线程。 这里线程已停止正常,但我无法再次启动该线程,请帮忙。 还给我解释一下 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;
}
}
主要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)
线程是不可重入的,即一旦退出run
方法,就不能重新启动,需要新建一个实例。
一个解决方案是创建一个 Sync
的新实例并启动它,但根据您的代码,更好的解决方案可能是使用 wait
锁 "pause" 线程并允许它恢复,例如...
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);
}
}
这基本上设置了两个循环,一个是保持线程 运行ning 直到 "terminated",另一个是捕获 "pause" 条件...
然后你可以做类似...
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
,原因有很多,但您会发现其中一个最有用future is Runnable
在 API 的不同部分(如 Executors
API)得到更广泛的支持,使其成为一个更加灵活的选项
看看Concurrency Trail for more details, in particular Lock Objects