同步通知,等待属性Boolean Object Java,IllegalMonitorStateException [英] synchronized notify, wait over property Boolean Object Java, IllegalMonitorStateException

查看:130
本文介绍了同步通知,等待属性Boolean Object Java,IllegalMonitorStateException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这个代码.

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

public class SyncProt0 {

  public static void main(String... args) {
    ExecutorService executorService = Executors.newCachedThreadPool();

    ProcessStep psWorker = new ProcessStep();
    ProcessStep psBoss = new ProcessStep();

    Worker worker = new Worker(executorService, psWorker, psBoss);
    Boss boss = new Boss(executorService, psBoss, psWorker);
  }

  public static class Worker implements Runnable {

    private final ProcessStep psWorker;
    private final ProcessStep psBoss;

    public Worker(ExecutorService executorService, ProcessStep psWorker, ProcessStep psBoss) {
      this.psWorker = psWorker;
      this.psBoss = psBoss;
      executorService.submit(this);
    }

    @Override
    public void run() {
      System.out.println("I'm -> Worker. I wait until Boss can see me!");
      while (!psBoss.isRunning()) {
        try {
          Thread.sleep(100);
        } catch (Exception e) { }
      }
      System.out.println("I'm -> Worker. Boss is seeing to me!");
      int counter = 0;
      while (counter < 6) {
        psWorker.setRunning(true);
        System.out.println("I'm Working ...");
        try {
          Thread.sleep(1000);
        } catch (Exception e) { }
        counter++;
      }
      psWorker.setRunning(false);
      psWorker.setFinished(true);
      System.out.println("I'm -> Worker. I left to work!");
    }

  }

  public static class Boss implements Runnable {
    private final ProcessStep psBoss;
    private final ProcessStep psWorker;
    private boolean running;

    public Boss(ExecutorService executorService, ProcessStep psBoss, ProcessStep psWorker) {
      this.psBoss = psBoss;
      this.psWorker = psWorker;

      executorService.submit(() -> {
        System.out.println("Boss. I have Runnable for turn of me when is needed");
        while (!this.psWorker.isFinished()) {
          try {
            Thread.sleep(100);
          } catch (InterruptedException e) { }
        }
        this.running = false;
      });
      executorService.submit(this);
    }

    @Override
    public void run() {
      System.out.println("I'm -> Boss. I'm delayed 4 Secs");
      try {
        Thread.sleep(4000);
      } catch (Exception e) { }

      System.out.println("I'm -> Boss. Let's go to check the work!");
      psBoss.setRunning(true);
      running = true;
      while (running) {
        System.out.println("I'm Checking ...");
        try {
          Thread.sleep(1000);
        } catch (Exception e) { }
      }
      psBoss.setRunning(false);
      psBoss.setFinished(true);
      System.out.println("I'm -> Boss The work end!");
    }

  }

  public static class ProcessStep {

    private final ReadWriteLock rwLock;
    private Boolean running;
    private Boolean finished;

    public ProcessStep() {
      this.rwLock = new ReentrantReadWriteLock();
      running = false;
      finished = false;
    }

    public Boolean isRunning() {
      Lock readLock = rwLock.readLock();
      readLock.lock();
      try {
        return running;
      } finally {
        readLock.unlock();
      }
    }

    public void setRunning(Boolean running) {
      Lock writeLock = rwLock.writeLock();
      writeLock.lock();
      try {
        this.running = running;
      } finally {
        writeLock.unlock();
      }
    }

    public Boolean isFinished() {
      Lock readLock = rwLock.readLock();
      readLock.lock();
      try {
        return finished;
      } finally {
        readLock.unlock();
      }
    }

    public void setFinished(Boolean finished) {
      Lock writeLock = rwLock.writeLock();
      writeLock.lock();
      try {
        this.finished = finished;
      } finally {
        writeLock.unlock();
      }
    }

  }

}

正确的输出是:

I'm -> Worker. I wait until Boss can see me!
Boss. I have Runnable for turn of me when is needed
I'm -> Boss. I'm delayed 4 Secs
I'm -> Boss. Let's go to check the work!
I'm Checking ...
I'm -> Worker. Boss is seeing to me!
I'm Working ...
I'm Checking ...
I'm Working ...
I'm Checking ...
I'm Working ...
I'm Checking ...
I'm Working ...
I'm Checking ...
I'm Working ...
I'm Checking ...
I'm Working ...
I'm Checking ...
I'm -> Worker. I left to work!
I'm -> Boss The work end!

工作正常!

注意::我不想只按需阻止所有 ProcessStep

NOTE: I don't want to block all ProcessStep only some property on demand!

我想在更改此代码(在Boss类中)的属性上使用WaitNotify机制:

I want to use Wait and Notify mechanism over the property changing this code (in Boss class):

    while (!this.psWorker.isFinished()) {
      try {
        Thread.sleep(100);
      } catch (InterruptedException e) {
      }
    }

和此代码(在Worker类中)

      while (!psBoss.isRunning()) {
        try {
          Thread.sleep(100);
        } catch (Exception e) {
        }
      }

当我用以下代码更改WorkerBoss类时:

When I changed the Worker and Boss classes with this code:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

public class SyncProt1 {

  public static void main(String... args) {
    ExecutorService executorService = Executors.newCachedThreadPool();

    ProcessStep psWorker = new ProcessStep();
    ProcessStep psBoss = new ProcessStep();

    Worker worker = new Worker(executorService, psWorker, psBoss);
    Boss boss = new Boss(executorService, psBoss, psWorker);
  }

  public static class Worker implements Runnable {
    private final ProcessStep psWorker;
    private final ProcessStep psBoss;

    public Worker(ExecutorService executorService, ProcessStep psWorker, ProcessStep psBoss) {
      this.psWorker = psWorker;
      this.psBoss = psBoss;
      executorService.submit(this);

    }

    @Override
    public void run() {
      System.out.println("I'm -> Worker. I wait until Boss can see me!");
      synchronized (this.psBoss.isRunning()) {
        try {
          psBoss.isRunning().wait();
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
      }
      System.out.println("I'm -> Worker. Boss is seeing to me!");
      int counter = 0;
      while (counter < 6) {
        synchronized (this.psWorker.isRunning()) {
          psWorker.setRunning(true);
          psWorker.isRunning().notify();
        }
        System.out.println("I'm Working ...");
        try {
          Thread.sleep(1000);
        } catch (Exception e) { }
        counter++;
      }
      synchronized (this.psWorker.isRunning()) {
        psWorker.setRunning(false);
        psWorker.isRunning().notify();
      }
      synchronized (this.psWorker.isFinished()) {
        psWorker.setFinished(true);
        psWorker.isFinished().notify();
      }
      System.out.println("I'm -> Worker. I left to work!");
    }

  }

  public static class Boss implements Runnable {
    private final ProcessStep psBoss;
    private final ProcessStep psWorker;
    private boolean running;

    public Boss(ExecutorService executorService, ProcessStep psBoss, ProcessStep psWorker) {
      this.psBoss = psBoss;
      this.psWorker = psWorker;

      executorService.submit(() -> {
        System.out.println("Boss. I have Runnable for turn of me when is needed");
        synchronized (this.psWorker.isFinished()) {
          try {
            psWorker.isFinished().wait();
          } catch (InterruptedException e) {
            e.printStackTrace();
          }
        }
        this.running = false;
      });
      executorService.submit(this);
    }

    @Override
    public void run() {
      System.out.println("I'm -> Boss. I'm delayed 4 Secs");
      try {
        Thread.sleep(4000);
      } catch (Exception e) { }

      System.out.println("I'm -> Boss. Let's go to check the work!");
      synchronized (this.psBoss.isRunning()) {
        psBoss.setRunning(true);
        psBoss.isRunning().notifyAll();
      }
      running = true;
      while (running) {
        System.out.println("I'm Checking ...");
        try {
          Thread.sleep(1000);
        } catch (Exception e) { }
      }
      synchronized (this.psBoss.isRunning()) {
        psBoss.setRunning(false);
        psBoss.isRunning().notify();
      }
      synchronized (this.psBoss.isFinished()) {
        psBoss.setFinished(true);
        psBoss.isFinished().notify();
      }
      System.out.println("I'm -> Boss The work end!");
    }

  }

  public static class ProcessStep {

    private final ReadWriteLock rwLock;
    private Boolean running;
    private Boolean finished;

    public ProcessStep() {
      this.rwLock = new ReentrantReadWriteLock();
      running = false;
      finished = false;
    }

    public Boolean isRunning() {
      Lock readLock = rwLock.readLock();
      readLock.lock();
      try {
        return running;
      } finally {
        readLock.unlock();
      }
    }

    public void setRunning(Boolean running) {
      Lock writeLock = rwLock.writeLock();
      writeLock.lock();
      try {
        this.running = running;
      } finally {
        writeLock.unlock();
      }
    }

    public Boolean isFinished() {
      Lock readLock = rwLock.readLock();
      readLock.lock();
      try {
        return finished;
      } finally {
        readLock.unlock();
      }
    }

    public void setFinished(Boolean finished) {
      Lock writeLock = rwLock.writeLock();
      writeLock.lock();
      try {
        this.finished = finished;
      } finally {
        writeLock.unlock();
      }
    }

  }

}

输出为

I'm -> Worker. I wait until Boss can see me!
Boss. I have Runnable for turn of me when is needed
I'm -> Boss. I'm delayed 4 Secs
I'm -> Boss. Let's go to check the work!

Worker仍在等待!

是否可以在属性上使用同步?

另一个具有相同结果的版本是:

Another version with same result was:

  public static class Worker implements Runnable {
    private final ProcessStep psWorker;
    private final ProcessStep psBoss;

    public Worker(ExecutorService executorService, ProcessStep psWorker, ProcessStep psBoss) {
      this.psWorker = psWorker;
      this.psBoss = psBoss;
      executorService.submit(this);

    }

    @Override
    public void run() {
      System.out.println("I'm -> Worker. I wait until Boss can see me!");
      synchronized (psBoss) {
        try {
          psBoss.isRunning().wait();
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
      }
      System.out.println("I'm -> Worker. Boss is seeing to me!");
      int counter = 0;
      while (counter < 6) {
        synchronized (psWorker) {
          psWorker.setRunning(true);
          psWorker.isRunning().notify();
        }
        System.out.println("I'm Working ...");
        try {
          Thread.sleep(1000);
        } catch (Exception e) { }
        counter++;
      }
      synchronized (psWorker) {
        psWorker.setRunning(false);
        psWorker.isRunning().notify();
      }
      synchronized (psWorker) {
        psWorker.setFinished(true);
        psWorker.isFinished().notify();
      }
      System.out.println("I'm -> Worker. I left to work!");
    }

  }

  public static class Boss implements Runnable {
    private final ProcessStep psBoss;
    private final ProcessStep psWorker;
    private boolean running;

    public Boss(ExecutorService executorService, ProcessStep psBoss, ProcessStep psWorker) {
      this.psBoss = psBoss;
      this.psWorker = psWorker;

      executorService.submit(() -> {
        System.out.println("Boss. I have Runnable for turn of me when is needed");
        synchronized (psWorker) {
          try {
            psWorker.isFinished().wait();
          } catch (InterruptedException e) {
            e.printStackTrace();
          }
        }
        this.running = false;
      });
      executorService.submit(this);
    }

    @Override
    public void run() {
      System.out.println("I'm -> Boss. I'm delayed 4 Secs");
      try {
        Thread.sleep(4000);
      } catch (Exception e) { }

      System.out.println("I'm -> Boss. Let's go to check the work!");
      synchronized (psBoss) {
        psBoss.setRunning(true);
        psBoss.isRunning().notifyAll();
      }
      running = true;
      while (running) {
        System.out.println("I'm Checking ...");
        try {
          Thread.sleep(1000);
        } catch (Exception e) { }
      }
      synchronized (psBoss) {
        psBoss.setRunning(false);
        psBoss.isRunning().notify();
      }
      synchronized (psBoss) {
        psBoss.setFinished(true);
        psBoss.isFinished().notify();
      }
      System.out.println("I'm -> Boss The work end!");
    }

  }

推荐答案

我想,我明白了!

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

public class SyncProt1 {

  public static void main(String... args) {
    List<Future<?>> futureList = new ArrayList<>();
    ExecutorService executorService = Executors.newCachedThreadPool();
    ProcessStep psWorker = new ProcessStep();
    ProcessStep psBoss = new ProcessStep();

    Worker worker = new Worker(futureList, executorService, psWorker, psBoss);
    Boss boss = new Boss(futureList, executorService, psBoss, psWorker);
  }

  public static class Worker implements Runnable {

    private final ProcessStep psWorker;
    private final ProcessStep psBoss;

    public Worker(List<Future<?>> futureList, ExecutorService executorService, ProcessStep psWorker, ProcessStep psBoss) {
      this.psWorker = psWorker;
      this.psBoss = psBoss;
      futureList.add(executorService.submit(this));
    }

    @Override
    public void run() {
      System.out.println("I'm -> Worker. I wait until Boss can see me!");
      synchronized (this.psBoss.getRunning()) {
        try {
          this.psBoss.getRunning().wait();
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
      }
      System.out.println("I'm -> Worker. Boss is seeing to me!");
      int counter = 0;
      while (counter < 6) {
        synchronized (this.psWorker.getRunning()) {
          this.psWorker.getRunning().setStep(Boolean.TRUE);
          psWorker.getRunning().notify();
        }
        System.out.println("I'm Working ...");
        try {
          Thread.sleep(1000);
        } catch (Exception e) {
        }
        counter++;
      }
      synchronized (this.psWorker.getRunning()) {
        this.psWorker.getRunning().setStep(Boolean.FALSE);
        this.psWorker.getRunning().notify();
      }
      synchronized (this.psWorker.getFinished()) {
        this.psWorker.getFinished().setStep(Boolean.TRUE);
        this.psWorker.getFinished().notify();
      }
      System.out.println("I'm -> Worker. I left to work!");
    }

  }

  public static class Boss implements Runnable {

    private final ProcessStep psBoss;
    private final ProcessStep psWorker;
    private boolean running;

    public Boss(List<Future<?>> futureList, ExecutorService executorService, ProcessStep psBoss, ProcessStep psWorker) {
      this.psBoss = psBoss;
      this.psWorker = psWorker;

      futureList.add(executorService.submit(() -> {
        System.out.println("Boss. I have Runnable for turn of me when is needed");
        synchronized (this.psWorker.getFinished()) {
          try {
            this.psWorker.getFinished().wait();
          } catch (InterruptedException e) {
            e.printStackTrace();
          }
        }
        System.out.println("Boss. The worker Finished!");
        this.running = false;
      }));
      futureList.add(executorService.submit(this));
    }

    @Override
    public void run() {
      System.out.println("I'm -> Boss. I'm delayed 4 Secs. " + new Date());
      try {
        Thread.sleep(4000);
      } catch (Exception e) {
      }

      System.out.println("I'm -> Boss. Let's go to check the work at " + new Date());
      synchronized (this.psBoss.getRunning()) {
        this.psBoss.getRunning().setStep(Boolean.TRUE);
        this.psBoss.getRunning().notify();
      }
      running = true;
      while (running) {
        System.out.println("I'm Checking ...");
        try {
          Thread.sleep(1000);
        } catch (Exception e) {
        }
      }
      synchronized (this.psBoss.getRunning()) {
        this.psBoss.getRunning().setStep(Boolean.FALSE);
        this.psBoss.getRunning().notify();
      }
      synchronized (this.psBoss.getFinished()) {
        this.psBoss.getFinished().setStep(Boolean.TRUE);
        this.psBoss.getFinished().notify();
      }
      System.out.println("I'm -> Boss The work end!");
    }

  }

  public static class ProcessStep {

    private final Step created = new Step();
    private final Step running = new Step();
    private final Step finished = new Step();

    public Step getCreated() {
      return created;
    }

    public Step getRunning() {
      return running;
    }

    public Step getFinished() {
      return finished;
    }

  }

  public static class Step {

    private final ReadWriteLock rwLock;
    private Boolean step;

    public Step() {
      this.rwLock = new ReentrantReadWriteLock();
      step = false;
    }

    public Boolean getStep() {
      Lock readLock = rwLock.readLock();
      readLock.lock();
      try {
        return step;
      } finally {
        readLock.unlock();
      }
    }

    public void setStep(Boolean step) {
      Lock writeLock = rwLock.writeLock();
      writeLock.lock();
      try {
        this.step = step;
      } finally {
        writeLock.unlock();
      }
    }

  }

}

输出

I'm -> Worker. I wait until Boss can see me!
Boss. I have Runnable for turn of me when is needed
I'm -> Boss. I'm delayed 4 Secs. Mon Aug 19 20:30:44 COT 2019
I'm -> Boss. Let's go to check the work at Mon Aug 19 20:30:48 COT 2019
I'm Checking ...
I'm -> Worker. Boss is seeing to me!
I'm Working ...
I'm Checking ...
I'm Working ...
I'm Checking ...
I'm Working ...
I'm Working ...
I'm Checking ...
I'm Checking ...
I'm Working ...
I'm Checking ...
I'm Working ...
I'm Checking ...
I'm -> Worker. I left to work!
Boss. The worker Finished!
I'm -> Boss The work end!

编辑.删除LockReadWriteLockReentrantReadWriteLock.进行同步并编辑getStepsetStep方法.

EDIT Removing Lock, ReadWriteLock and ReentrantReadWriteLock. Doing synchronized and Editing getStep and setStep methods.

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class SyncProt4 {

  public static void main(String... args) {
    List<Future<?>> futureList = new ArrayList<>();
    ExecutorService executorService = Executors.newCachedThreadPool();
    ProcessStep psWorker = new ProcessStep();
    ProcessStep psBoss = new ProcessStep();

    Worker worker = new Worker(futureList, executorService, psWorker, psBoss);
    Boss boss = new Boss(futureList, executorService, psBoss, psWorker);

  }

  public static class Worker implements Runnable {

    private final ProcessStep psWorker;
    private final ProcessStep psBoss;

    public Worker(List<Future<?>> futureList, ExecutorService executorService, ProcessStep psWorker, ProcessStep psBoss) {
      this.psWorker = psWorker;
      this.psBoss = psBoss;
      futureList.add(executorService.submit(this));
    }

    @Override
    public void run() {
      System.out.println("I'm Worker -> I wait until Boss can see me!");
      while (!this.psBoss.getRunning().getStep());

      System.out.println("I'm Worker -> Boss is seeing to me!");
      int counter = 0;
      while (counter < 6) {
        this.psWorker.getRunning().setStep(Boolean.TRUE);
        System.out.println("I'm Worker -> I'm Working ...");
        try {
          Thread.sleep(1000);
        } catch (Exception e) {
        }
        counter++;
      }
      this.psWorker.getRunning().setStep(Boolean.FALSE);
      this.psWorker.getFinished().setStep(Boolean.TRUE);
      System.out.println("I'm Worker -> I left to work!");
    }

  }

  public static class Boss implements Runnable {

    private final ProcessStep psBoss;
    private final ProcessStep psWorker;
    private boolean running;

    public Boss(List<Future<?>> futureList, ExecutorService executorService, ProcessStep psBoss, ProcessStep psWorker) {
      this.psBoss = psBoss;
      this.psWorker = psWorker;

      futureList.add(executorService.submit(() -> {
        System.out.println("I'm Boss -> I have Runnable for turn of me when is needed");
        while (!this.psWorker.getFinished().getStep());
        System.out.println("I'm Boss -> The Worker Finished!");
        this.running = false;
      }));
      futureList.add(executorService.submit(this));
    }

    @Override
    public void run() {
      System.out.println("I'm Boss -> I'm delayed 4 Secs. " + new Date());
      try {
        Thread.sleep(4000);
      } catch (Exception e) {
      }

      System.out.println("I'm Boss -> Let's go to check the work at " + new Date());
      this.psBoss.getRunning().setStep(Boolean.TRUE);
      running = true;
      while (running) {
        System.out.println("I'm Boss -> I'm Checking ...");
        try {
          Thread.sleep(1000);
        } catch (Exception e) {
        }
      }
      this.psBoss.getRunning().setStep(Boolean.FALSE);
      this.psBoss.getFinished().setStep(Boolean.TRUE);
      System.out.println("I'm Boss -> The work ends!");
    }

  }

  public static class ProcessStep {

    private final Step created = new Step();
    private final Step running = new Step();
    private final Step finished = new Step();

    public Step getCreated() {
      return created;
    }

    public Step getRunning() {
      return running;
    }

    public Step getFinished() {
      return finished;
    }

  }

  public static class Step {

    private Boolean step;

    public Step() {
      step = false;
    }

    public synchronized Boolean getStep() {
      try {
        wait();
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
      return step;
    }

    public synchronized void setStep(Boolean step) {
      this.step = step;
      notifyAll();
    }

  }

}

新输出

I'm Worker -> I wait until Boss can see me!
I'm Boss -> I have Runnable for turn of me when is needed
I'm Boss -> I'm delayed 4 Secs. Tue Aug 20 21:27:26 COT 2019
I'm Boss -> Let's go to check the work at Tue Aug 20 21:27:30 COT 2019
I'm Boss -> I'm Checking ...
I'm Worker -> Boss is seeing to me!
I'm Worker -> I'm Working ...
I'm Boss -> I'm Checking ...
I'm Worker -> I'm Working ...
I'm Boss -> I'm Checking ...
I'm Worker -> I'm Working ...
I'm Boss -> I'm Checking ...
I'm Worker -> I'm Working ...
I'm Boss -> I'm Checking ...
I'm Worker -> I'm Working ...
I'm Boss -> I'm Checking ...
I'm Worker -> I'm Working ...
I'm Worker -> I left to work!
I'm Boss -> The Worker Finished!
I'm Boss -> I'm Checking ...
I'm Boss -> The work ends!

这篇关于同步通知,等待属性Boolean Object Java,IllegalMonitorStateException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆