gpt4 book ai didi

java - 使用java的多线程概念控制运行线程

转载 作者:行者123 更新时间:2023-11-30 08:48:52 26 4
gpt4 key购买 nike

我只想在按下回车键时启动和停止线程。这里线程已停止正常,但我无法再次启动该线程,请帮忙。还向我解释了 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;
}



}

主类``

    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 锁来“暂停”线程并允许它恢复,例如...

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,原因有很多,但您会发现 future 最有用的是 Runnable 在 API 的不同部分(如 Executors API)得到更广泛的支持,使其成为一个更加灵活的选择

看看 Concurrency Trail了解更多详情,特别是 Lock Objects

关于java - 使用java的多线程概念控制运行线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31715950/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com