这是使用java线程的示例代码。问题是我无法暂停该帖子。
public class RunnableDemo implements Runnable {
public Thread t;
private String threadName;
boolean suspended = false;
RunnableDemo( String name){
threadName = name;
System.out.println("Creating " + threadName );
}
public void run() {
System.out.println("Running " + threadName );
try {
while (true) {
System.out.println("Thread: " + threadName + ", " + i);
// Let the thread sleep for a while.
Thread.sleep(300);
synchronized(this) {
while(suspended) {
wait();
}
}
}
} catch (InterruptedException e) {
System.out.println("Thread " + threadName + " interrupted.");
}
System.out.println("Thread " + threadName + " exiting.");
}
public void start ()
{
System.out.println("Starting " + threadName );
if (t == null)
{
t = new Thread (this, threadName);
t.start ();
}
}
public void suspend() {
suspended = true;
}
下面的暂停功能不起作用:
RunnableDemo R1 = new RunnableDemo( "Thread-1");
R1.start();
R1.suspend(); // This line does not work and thread continues ...
实际上,当我调用suspended
时,线程看不到suspend()
的新值。有什么想法吗?
答案 0 :(得分:3)
将suspended
声明为volatile
:
volatile boolean suspended = false;
答案 1 :(得分:1)
我并不完全清楚你想要达到的目标,但这里有一些观察和提示可能有所帮助:
suspend()
方法时,第二个线程" Thread-1"可能甚至没有进入循环。如果在suspend()
以及wait()
之前和之后添加更多调试输出,您将看到此信息。反之亦然,您可以在wait()
设置为true之前调用suspend
。然后,一旦调用wait()
,您就不会在" Thread-1"中看到更多更新。因为它在等待。wait()
方法永远不会返回。要实现此目的,请在调用wait()
时同步您同步的同一对象,即在main方法中调用R1
并在此对象上调用notifyAll()
。您也可以在suspend()
方法中执行此操作。Thread.sleep()
之类的方法变得非常不必要。呼叫wait()
没有主动等待,并且不会消耗大量资源。简而言之,将暂停方法更改为
void suspend() {
suspended = true;
synchronized (this) {
this.notifyAll();
}
}
这将改变您的程序行为方式,并使其更加清晰。但无论哪种方式,它似乎都没有"暂停"这个方法在之前或之后的作用是一个很好的名称,但如果你试验这个,你可以更好地理解你如何实现你想要达到的目标。
答案 2 :(得分:1)
使用wait()可能无法按预期工作。 wait / notify构建为并发编程的sempaphore(作为对象实例范围监视器)上下文的简单实现。 从没有锁定线程对象实例的监视器的任何其他线程调用notify()都不起作用,请参阅Java Wait and Notify: IllegalMonitorStateException
您可以通过定期检查暂停标志轻松实现目标,如果您的主题不做任何事情,请稍等一下:
public class SuspendDemo implements Runnable {
public Thread t;
private final String threadName;
boolean suspended = false;
SuspendDemo(final String name){
threadName = name;
System.out.println("Creating " + threadName );
}
@Override
public void run() {
System.out.println("Running " + threadName );
try {
while (true) {
System.out.println("Thread: " + threadName);
// Let the thread sleep for a while.
Thread.sleep(300);
while(suspended) {
System.out.println("suspended");
Thread.sleep(50);
}
}
} catch (final InterruptedException e) {
System.out.println("Thread " + threadName + " interrupted.");
}
System.out.println("Thread " + threadName + " exiting.");
}
public void start () {
System.out.println("Starting " + threadName );
if (t == null) {
t = new Thread (this, threadName);
t.start ();
}
}
void suspend() {
suspended = true;
}
void resume() {
suspended = false;
notify();
}
public static void main(final String[] args) throws InterruptedException {
final SuspendDemo R1 = new SuspendDemo( "Thread-1");
R1.start();
R1.suspend();
Thread.sleep(500);
R1.resume();
}
}
由于:
> Creating Thread-1
> Starting Thread-1
> Running Thread-1
> Thread: Thread-1
> suspended
> suspended
> suspended
> suspended
> Thread: Thread-1
> Thread: Thread-1
> Thread: Thread-1
suspend标志是一个本机布尔值,因此写入它是一个原子操作,因此你可以不进行任何同步。 我建议在使用synchronized之前完全理解并发编程和Java使用的监视器并发模型。我发现使用synchronize(this)块很难维护并且容易出错。
下一个示例使用 wait()和 notifyAll()解决了问题。请注意使用synchronized方法来锁定线程对象的监视器而不是同步(this)块。
public class SuspendDemo implements Runnable {
public Thread t;
private final String threadName;
boolean suspended = false;
SuspendDemo(final String name){
threadName = name;
System.out.println("Creating " + threadName );
}
@Override
public void run() {
System.out.println("Running " + threadName );
try {
while (true) {
System.out.println("Thread: " + threadName);
// Let the thread sleep for a while.
Thread.sleep(300);
work();
}
} catch (final InterruptedException e) {
System.out.println("Thread " + threadName + " interrupted.");
}
System.out.println("Thread " + threadName + " exiting.");
}
synchronized protected void work() throws InterruptedException {
while(suspended) {
System.out.println("suspended");
wait();
System.out.println("resumed");
}
}
public void start () {
System.out.println("Starting " + threadName );
if (t == null) {
t = new Thread (this, threadName);
t.start ();
}
}
synchronized void suspend() {
suspended = true;
notifyAll();
}
synchronized void resume() {
suspended = false;
notifyAll();
}
public static void main(final String[] args) throws InterruptedException {
final SuspendDemo R1 = new SuspendDemo( "Thread-1");
R1.start();
R1.suspend();
Thread.sleep(500);
R1.resume();
}
}