Java 在清单7.15中的;“实践中的并发性”;,内部类和外部类如何在“上同步?”;这是什么;? 公共类日志服务{ 私有最终阻塞队列; 专用最终LoggerThread LoggerThread; 私人最终印刷作家; @GuardedBy(“此”)私有布尔值设置; @由(“本”)私人int保留担保; public void start(){loggerThread.start();} 公共停车场(){ 已同步(此){IsShutton=true;} loggerThread.interrupt(); } 公共无效日志(字符串msg)引发InterruptedException{ 已同步(此){ 如果(isShutdown) 抛出新的非法状态异常(…); ++保留; } queue.put(msg); } 私有类LoggerThread扩展线程{ 公开募捐{ 试一试{ while(true){ 试一试{ 已同步(此){ 如果(isShutdown&&reservations==0) 打破 } 字符串msg=queue.take(); 已同步(此){--reservations;} writer.println(msg); }捕获(中断异常e){/*重试*/} } }最后{ writer.close(); } } } }

Java 在清单7.15中的;“实践中的并发性”;,内部类和外部类如何在“上同步?”;这是什么;? 公共类日志服务{ 私有最终阻塞队列; 专用最终LoggerThread LoggerThread; 私人最终印刷作家; @GuardedBy(“此”)私有布尔值设置; @由(“本”)私人int保留担保; public void start(){loggerThread.start();} 公共停车场(){ 已同步(此){IsShutton=true;} loggerThread.interrupt(); } 公共无效日志(字符串msg)引发InterruptedException{ 已同步(此){ 如果(isShutdown) 抛出新的非法状态异常(…); ++保留; } queue.put(msg); } 私有类LoggerThread扩展线程{ 公开募捐{ 试一试{ while(true){ 试一试{ 已同步(此){ 如果(isShutdown&&reservations==0) 打破 } 字符串msg=queue.take(); 已同步(此){--reservations;} writer.println(msg); }捕获(中断异常e){/*重试*/} } }最后{ writer.close(); } } } },java,concurrency,Java,Concurrency,这是《实践中的Java并发》一书中的清单7.15。我不明白同步在那里是如何工作的。为什么内部类和外部类在访问字段的不同对象上同步? 是否存在此错误,并且内部类必须使用synchronize(LogService.this)?或者我完全误解了同步是如何工作的?这是书中的一个错误,在 p、 154:在清单7.15中,最后两个同步(this)行应为synchronized(LogService.this) 你说得对,这里有个错误。它应该是LogService.this in LoggerThread-

这是《实践中的Java并发》一书中的清单7.15。我不明白同步在那里是如何工作的。为什么内部类和外部类在访问字段的不同对象上同步?
是否存在此错误,并且内部类必须使用synchronize(LogService.this)?或者我完全误解了同步是如何工作的?

这是书中的一个错误,在

p、 154:在清单7.15中,最后两个同步(this)行应为synchronized(LogService.this)


你说得对,这里有个错误。它应该是LogService.this in LoggerThread-否则在修改过程中保留可能会损坏(因为-+是加载、修改、存储,而不是原子操作)。此外,锁可能会被智能jvm完全忽略,因为它们永远不会受到质疑(在这种情况下,甚至内存可见性也可能受到影响)!
public class LogService {
  private final BlockingQueue<String> queue;
  private final LoggerThread loggerThread;
  private final PrintWriter writer;
  @GuardedBy("this") private boolean isShutdown;
  @GuardedBy("this") private int reservations;
  public void start() { loggerThread.start(); }
  public void stop() {
      synchronized (this) { isShutdown = true; }
      loggerThread.interrupt();
  }
  public void log(String msg) throws InterruptedException {
      synchronized (this) {
          if (isShutdown)
              throw new IllegalStateException(...);
          ++reservations;
      }
      queue.put(msg);
  }
  private class LoggerThread extends Thread {
      public void run() {
          try {
              while (true) {
                  try {
                      synchronized (this) {
                          if (isShutdown && reservations == 0)
                              break;
                      }
                      String msg = queue.take();
                      synchronized (this) { --reservations; }
                      writer.println(msg);
                  } catch (InterruptedException e) { /* retry */ }
              }
          } finally {
              writer.close();
          }
      }
  }
}