Java 如何确定线程是否正在执行操作

Java 如何确定线程是否正在执行操作,java,multithreading,Java,Multithreading,我有一个简单的类,它扩展了thread类,它有run方法,如下所示: public void run() { while(running) { if(enabled) { doStep(); enabled = false; } else { try { this.sleep(1000);

我有一个简单的类,它扩展了thread类,它有run方法,如下所示:

public void run() {

    while(running) {

        if(enabled)
        {
            doStep();
            enabled = false;
        }
        else
        {
            try {
                this.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
当我想调用
myObject
时,我在代码的另一个地方调用
doStep()

但是如何确保
myObject
实际完成了
doStep()
方法?简单的

myObject.enable = true
while(myObject.isEnabled())
{
;
}
doActionAfterObjectFinish();
有时会导致程序卡在循环中,当然
doStep()
不会导致它

@谢谢你的回答,而不是使用sempahores。如果我以这种方式更改代码,会有帮助吗

    public void run() {

        while(running) {

            if(enabled)
            {
                synchronized(this){
                doStep();
                enabled = false;
}
            }
            else
            {
                try {
                    this.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

public synchronized boolean isEnabled() {
return enabled;
}

首先,确保
myObject.enable
变量声明为
volatile

第二,我建议使用
java.util.concurrent
包对您试图建模的内容进行建模。。。可能是一个可以帮助你

import java.util.concurrent.Semaphore;

public class Example {

  public static void main(String[] args) throws InterruptedException {
    MyRunnable target = new MyRunnable();
    Thread thread2    = new Thread(target);

    thread2.start();
    target.waitUntilFinish();

    System.out.println("MyRunnable ends first!");
  }


  public static class MyRunnable implements Runnable {

    private Semaphore workDone = new Semaphore(0);
    private int count;

    @Override
    public void run() {
        while (true) {
            // heavy work here...
            if (this.count < 5) {
                System.out.println("Iteration: " + (++this.count));
            } else {
                this.workDone.release();
                break;
            }
            try { Thread.sleep(2000L); } catch (InterruptedException ex) { }
        }
    }

    public void waitUntilFinish() throws InterruptedException {
        this.workDone.acquire();
    }
  }
}
import java.util.concurrent.Semaphore;
公开课范例{
公共静态void main(字符串[]args)引发InterruptedException{
MyRunnable target=新建MyRunnable();
线程线程2=新线程(目标);
thread2.start();
target.waitUntilFinish();
System.out.println(“MyRunnable首先结束!”);
}
公共静态类MyRunnable实现Runnable{
专用信号量workDone=新信号量(0);
私人整数计数;
@凌驾
公开募捐{
while(true){
//这里工作繁重。。。
如果(该计数小于5){
System.out.println(“迭代:”+(++this.count));
}否则{
this.workDone.release();
打破
}
尝试{Thread.sleep(2000L);}catch(InterruptedException ex){}
}
}
public void waitUntilFinish()引发InterruptedException{
this.workDone.acquire();
}
}
}

首先,确保
myObject.enable
变量声明为
volatile

第二,我建议使用
java.util.concurrent
包对您试图建模的内容进行建模。。。可能是一个可以帮助你

import java.util.concurrent.Semaphore;

public class Example {

  public static void main(String[] args) throws InterruptedException {
    MyRunnable target = new MyRunnable();
    Thread thread2    = new Thread(target);

    thread2.start();
    target.waitUntilFinish();

    System.out.println("MyRunnable ends first!");
  }


  public static class MyRunnable implements Runnable {

    private Semaphore workDone = new Semaphore(0);
    private int count;

    @Override
    public void run() {
        while (true) {
            // heavy work here...
            if (this.count < 5) {
                System.out.println("Iteration: " + (++this.count));
            } else {
                this.workDone.release();
                break;
            }
            try { Thread.sleep(2000L); } catch (InterruptedException ex) { }
        }
    }

    public void waitUntilFinish() throws InterruptedException {
        this.workDone.acquire();
    }
  }
}
import java.util.concurrent.Semaphore;
公开课范例{
公共静态void main(字符串[]args)引发InterruptedException{
MyRunnable target=新建MyRunnable();
线程线程2=新线程(目标);
thread2.start();
target.waitUntilFinish();
System.out.println(“MyRunnable首先结束!”);
}
公共静态类MyRunnable实现Runnable{
专用信号量workDone=新信号量(0);
私人整数计数;
@凌驾
公开募捐{
while(true){
//这里工作繁重。。。
如果(该计数小于5){
System.out.println(“迭代:”+(++this.count));
}否则{
this.workDone.release();
打破
}
尝试{Thread.sleep(2000L);}catch(InterruptedException ex){}
}
}
public void waitUntilFinish()引发InterruptedException{
this.workDone.acquire();
}
}
}

在CPU上使用多线程时,强烈建议使用信号量或锁。看看这个:还有。本质上,必须设置信号量或自旋锁,以便在需要时阻止代码,并在需要时解锁代码。这是一种常见且高度推荐的做法

一种可能对您有用的自旋锁伪代码是:

void thread1(){
   while(true){
      while(locked(lock1));

      lock(lock2);
      doActions();
      unlock(lock2);
   }
}

void thread2(){
  while(true){
      while(locked(spinlock2));

      lock(spinlock1);
      doStuff();
      unlock(spinlock1);
  }

}

在CPU上使用多线程时,强烈建议使用信号量或锁。看看这个:还有。本质上,必须设置信号量或自旋锁,以便在需要时阻止代码,并在需要时解锁代码。这是一种常见且高度推荐的做法

一种可能对您有用的自旋锁伪代码是:

void thread1(){
   while(true){
      while(locked(lock1));

      lock(lock2);
      doActions();
      unlock(lock2);
   }
}

void thread2(){
  while(true){
      while(locked(spinlock2));

      lock(spinlock1);
      doStuff();
      unlock(spinlock1);
  }

}

第一个想法是添加一个计数器,用于计算doStep()执行的频率。在doStep方法下面添加计数器+。然后,您可以像myObject.getRuntimes()>0一样在外部查询计数器。第一个想法是添加一个计数器,计算执行doStep()的频率。在doStep方法下面添加计数器+。然后,您可以在外部查询计数器,就像myObject.getRuntimes()>0.shoudl调用的my类
my.Object.isenaled()
可以访问“myObject”内部的信号量一样?谢谢您的回答和示例!我接受了,你能不能这么好,检查一下我编辑的代码中使用的
同步的
是否会以同样的方式工作?检查后谁会释放信号量?@whd,是的,你的代码也会以同样的方式工作。。。但请记住将变量
enable
声明为
volatile
;或者在同步方法或同步块代码处更改其值(如您所写)…关于信号量释放。。。。这取决于。。。信号量可以在任何地方或线程中释放(JAVA不对其施加任何限制)。。。所以,它必须在有更多逻辑的地方发布。。。在我的示例中,信号量开始“take”,因此对“waitUntilFinish”的任何调用都会阻塞(实际上,阻塞主线程),直到“run”方法释放它。。。此时,主线程也可以继续并释放信号量…应该让调用
my.Object.isnald()
的类访问“myObject”中的信号量吗?谢谢您的回答和示例!我接受了,你能不能这么好,检查一下我编辑的代码中使用的
同步的
是否会以同样的方式工作?检查后谁会释放信号量?@whd,是的,你的代码也会以同样的方式工作。。。但请记住将变量
enable
声明为
volatile
;或者在同步方法或同步块代码处更改其值(如您所写)…关于信号量释放。。。。这取决于。。。信号量可以在任何地方或线程中释放(JAVA不对其施加任何限制)。。。所以,它必须在有更多逻辑的地方发布。。。在我的示例中,信号量开始“take”,因此对“waitUntilFinish”的任何调用都会阻塞(事实上)