gpt4 book ai didi

java - 如何在 Java 中线程安全地发出线程暂停信号

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:54:02 27 4
gpt4 key购买 nike

我有一堆线程同时运行。有时一个线程需要通知其他线程等待它完成一项工作并再次向它们发出恢复信号。由于我对 Java 的同步有点陌生,所以我想知道做这种事情的正确方法是什么。我的代码是这样的:

private void Concurrent() {
if (shouldRun()) {
// notify threads to pause and wait for them
DoJob();
// resume threads
}

// Normal job...
}

更新:

请注意,我编写的代码位于一个将由每个线程执行的类中。我无权访问这些线程或它们的运行方式。我只是在线程中。

更新 2:

我的代码来自爬虫类。爬虫类 (crawler4j) 知道如何处理并发。我唯一需要做的就是在运行一个函数之前暂停其他爬虫,然后再恢复它们。这段代码是我的爬虫的基础:

   public class TestCrawler extends WebCrawler {
private SingleThread()
{
//When this function is running, no other crawler should do anything
}

@Override
public void visit(Page page) {
if(SomeCriteria())
{
//make all other crawlers stop until I finish
SingleThread();
//let them resume
}

//Normal Stuff
}
}

最佳答案

这里是一个简短的例子,说明如何使用酷炫的 Java 并发性实现这一目标:

剪断旧代码对于 Pause 类不再重要。

编辑:

这是新的测试类:

package de.hotware.test;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Test {

private Pause mPause;

public Test() {
this.mPause = new Pause();
}

public void concurrent() throws InterruptedException {
while(true) {
this.mPause.probe();
System.out.println("concurrent");
Thread.sleep(100);
}
}

public void crucial() throws InterruptedException {
int i = 0;
while (true) {
if (i++ % 2 == 0) {
this.mPause.pause(true);
System.out.println("crucial: exclusive execution");
this.mPause.pause(false);
} else {
System.out.println("crucial: normal execution");
Thread.sleep(1000);
}
}
}

public static void main(String[] args) {
final Test test = new Test();
Runnable run = new Runnable() {

@Override
public void run() {
try {
test.concurrent();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

};
Runnable cruc = new Runnable() {

@Override
public void run() {
try {
test.crucial();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

};
ExecutorService serv = Executors.newCachedThreadPool();
serv.execute(run);
serv.execute(run);
serv.execute(cruc);
}

}

还有实用程序 Pause 类:

package de.hotware.test;

import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
* Utility class to pause and unpause threads
* with Java Concurrency
* @author Martin Braun
*/
public class Pause {

private Lock mLock;
private Condition mCondition;
private AtomicBoolean mAwait;

public Pause() {
this.mLock = new ReentrantLock();
this.mCondition = this.mLock.newCondition();
this.mAwait = new AtomicBoolean(false);
}

/**
* waits until the threads until this.mAwait is set to true
* @throws InterruptedException
*/
public void probe() throws InterruptedException {
while(this.mAwait.get()) {
this.mLock.lock();
try {
this.mCondition.await();
} finally {
this.mLock.unlock();
}
}
}

/**
* pauses or unpauses
*/
public void pause(boolean pValue) {
if(!pValue){
this.mLock.lock();
try {
this.mCondition.signalAll();
} finally {
this.mLock.unlock();
}
}
this.mAwait.set(pValue);
}

}

基本用法是在每次运行前调用 probe()。如果暂停,这将阻塞直到调用 pause(false)。

你的类看起来像这样:

public class TestCrawler extends WebCrawler {

private Pause mPause;

public TestCrawler(Pause pPause) {
this.mPause = pPause;
}

private SingleThread()
{
//When this function is running, no other crawler should do anything
}

@Override
public void visit(Page page) {
if(SomeCriteria())
{
//only enter the crucial part once if it has to be exclusive
this.mPause.probe();
//make all other crawlers stop until I finish
this.mPause.pause(true);
SingleThread();
//let them resume
this.mPause.pause(false);
}
this.mPause.probe();
//Normal Stuff
}
}

关于java - 如何在 Java 中线程安全地发出线程暂停信号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14304074/

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