Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/eclipse/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java-使用ReentrantLock异步运行作业?_Java_Asynchronous_Reentrantlock - Fatal编程技术网

Java-使用ReentrantLock异步运行作业?

Java-使用ReentrantLock异步运行作业?,java,asynchronous,reentrantlock,Java,Asynchronous,Reentrantlock,下面的代码允许我们运行作业,同时通过使用ReentrantLock确保一次只能运行一个作业 是否有任何方法可以修改此代码以异步运行job.call(),并在启动线程之前将MyConcurrentJobException返回给客户端 我们尝试将try/catch/finally块包装在一个新的线程中,但是解锁和锁定必须发生在同一个线程中,因此我们得到了一个非法监视异常 ? 您可以使用Semaphore而不是ReentrantLock,它的许可证不绑定到线程 类似这样的情况(不确定在异步情况下如何处

下面的代码允许我们运行
作业
,同时通过使用
ReentrantLock
确保一次只能运行一个作业

是否有任何方法可以修改此代码以异步运行
job.call()
,并在启动线程之前将
MyConcurrentJobException
返回给客户端

我们尝试将try/catch/finally块包装在一个新的
线程中
,但是
解锁
锁定
必须发生在同一个线程中,因此我们得到了一个
非法监视异常

?


您可以使用
Semaphore
而不是
ReentrantLock
,它的许可证不绑定到线程

类似这样的情况(不确定在异步情况下如何处理
job.call()
的结果):


我认为我完全误解了这一点,因为在异步执行某些操作时阻塞和等待对我来说没有太大意义,除非在调用线程上取得一些进展

你能这样做吗:

final static Lock lock = new ReentrantLock();
final static ExecutorService service = Executors.newThreadPoolExecutor();
public Object runJob(String desc, Callable job, boolean wait) {
    logger.info("Acquiring lock");
    if (!lock.tryLock()) {
        throw new MyConcurrentJobException();
    }

    activeJob = new JobStatus(desc);
    logger.info("Lock acquired");

    try {
        Future<?> future = service.submit(job);
        // This next line will block until the job is finished
        // and also will hold onto the lock.
        boolean finished = false;
        Object o = null;
        while(!finished) {
            try {
                o = future.get(300, TimeUnit.MILLISECONDS);
                finished = true;
            catch(TimeOutException e) {
                // Do some periodic task while waiting
                // foot.tapLots();
            }
         }
         if (o instanceof MarginServiceAssertionException) {
             throw ((MargineServiceAssertionException)o);
         } else if (o instanceof MargineServiceSystemException) {
             throw ((MarginServiceSystemException)o);
         } else if (o instanceof Exception) {
             throw new MarginServiceSystemException(e);
         }
    } catch (... InterruptedException e) { /// catch whatever exceptions throws as part of this
       /// Whatever needs to be done.
    } finally {
        activeJob = null;
        logger.info("Releasing lock");
        lock.unlock();
        logger.info("Lock released");
    }
}
final static Lock=new ReentrantLock();
final static ExecutorService service=Executors.newThreadPoolExecutor();
公共对象运行作业(字符串描述、可调用作业、布尔等待){
logger.info(“获取锁”);
如果(!lock.tryLock()){
抛出新的MyConcurrentJobException();
}
activeJob=新作业状态(desc);
logger.info(“锁定已获取”);
试一试{
未来=服务。提交(作业);
//下一行将阻塞,直到作业完成
//也会抓住锁。
布尔完成=假;
对象o=null;
当(!完成){
试一试{
o=future.get(300,时间单位为毫秒);
完成=正确;
捕获(超时异常e){
//在等待时做一些定期任务
//脚。塔普洛特();
}
}
if(o MarginServiceAssertionException实例){
抛出((MargineServiceAssertionException)o);
}else if(o MargineServiceSystemException实例){
抛出((MarginServiceSystemException)o);
}else if(o实例异常){
抛出新的MarginServiceSystemException(e);
}
}catch(…InterruptedException e){///捕获作为此过程的一部分抛出的任何异常
///无论需要做什么。
}最后{
activeJob=null;
logger.info(“释放锁”);
lock.unlock();
logger.info(“锁已释放”);
}
}

我们希望使用gui启动作业。我们希望立即通过“您的作业已启动”消息将控制权返回gui。但我们希望防止并发作业发生。因此,如果用户试图在另一个作业正在进行时启动作业,他们会出错。啊,好的,那么我会使用axtavt的解决方案。
final static Semaphore lock = new Semaphore(1);

public void runJob(String desc, Callable job, boolean wait) {
    logger.info("Acquiring lock");
    if (!lock.tryAcquire()) {
        throw new MyConcurrentJobException();
    }

    startThread(new Runnable() {
        public void run() {
            try {
                job.call();
            } finally {
                lock.release();
            }
        }
    });    
}
final static Lock lock = new ReentrantLock();
final static ExecutorService service = Executors.newThreadPoolExecutor();
public Object runJob(String desc, Callable job, boolean wait) {
    logger.info("Acquiring lock");
    if (!lock.tryLock()) {
        throw new MyConcurrentJobException();
    }

    activeJob = new JobStatus(desc);
    logger.info("Lock acquired");

    try {
        Future<?> future = service.submit(job);
        // This next line will block until the job is finished
        // and also will hold onto the lock.
        boolean finished = false;
        Object o = null;
        while(!finished) {
            try {
                o = future.get(300, TimeUnit.MILLISECONDS);
                finished = true;
            catch(TimeOutException e) {
                // Do some periodic task while waiting
                // foot.tapLots();
            }
         }
         if (o instanceof MarginServiceAssertionException) {
             throw ((MargineServiceAssertionException)o);
         } else if (o instanceof MargineServiceSystemException) {
             throw ((MarginServiceSystemException)o);
         } else if (o instanceof Exception) {
             throw new MarginServiceSystemException(e);
         }
    } catch (... InterruptedException e) { /// catch whatever exceptions throws as part of this
       /// Whatever needs to be done.
    } finally {
        activeJob = null;
        logger.info("Releasing lock");
        lock.unlock();
        logger.info("Lock released");
    }
}