Java 如何确定线程是否正在执行操作
我有一个简单的类,它扩展了thread类,它有run方法,如下所示:Java 如何确定线程是否正在执行操作,java,multithreading,Java,Multithreading,我有一个简单的类,它扩展了thread类,它有run方法,如下所示: public void run() { while(running) { if(enabled) { doStep(); enabled = false; } else { try { this.sleep(1000);
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”的任何调用都会阻塞(事实上)