是否可以使用同步安全地访问该变量?

发布于 2024-12-24 22:37:26 字数 1333 浏览 4 评论 0原文

我有一个例子,Java 类有一个包含同步块的超类。

Class SuperClassA {
     private Bitmap bmpA;

     protected abstract Bitmap createBitmap();

     public void run() {
          synchronized (this) {
               bmpA = createBitmap();
          }
     }

     // some other codes.
}

Class SubClassB extends SuperClassA {
     private Bitmap outBmpB;

     protected Bitmap createBitmap() {
          outBmpB = ..... // create and process "outBmpB".

          Bitmap bmp;
          bmp = ..... // create and process "bmp".
          return bmp;
     }

     public Bitmap getOutBmpB() {
          Bitmap tempBmp;
          synchronized (this) {
               tempBmp = outBmpB.clone();
          }
          return tempBmp;
     }

     // some other codes.
}

B类中的“getOutBmpB()”方法由一个线程运行,而B类中继承的“run()”方法由另一个线程运行。 ClassB 中实现的“createBitmap()”方法应在“run()”方法内的同步块中运行。

我的问题是,我不确定ClassB中新定义的类变量“outBmpB”是否被两个线程安全地访问。我不确定“run()”方法中的“synchronized (this)”块是否也会“锁定”仅在 ClassB 中定义的“outBmpB”变量?如果没有,那么我可以在“createBitmap()”实现中添加“同步(此)”块吗?例如,

 protected Bitmap createBitmap() {
      synchronized (this) {
           outBmpB = ..... // create and process "outBmpB".
      }

      Bitmap bmp;
      bmp = ..... // create and process "bmp".
      return bmp;
 }

感谢您的任何建议。

劳伦斯

I have a case in which a Java class has a superclass that contains a synchronized block.

Class SuperClassA {
     private Bitmap bmpA;

     protected abstract Bitmap createBitmap();

     public void run() {
          synchronized (this) {
               bmpA = createBitmap();
          }
     }

     // some other codes.
}

Class SubClassB extends SuperClassA {
     private Bitmap outBmpB;

     protected Bitmap createBitmap() {
          outBmpB = ..... // create and process "outBmpB".

          Bitmap bmp;
          bmp = ..... // create and process "bmp".
          return bmp;
     }

     public Bitmap getOutBmpB() {
          Bitmap tempBmp;
          synchronized (this) {
               tempBmp = outBmpB.clone();
          }
          return tempBmp;
     }

     // some other codes.
}

The "getOutBmpB()" method in Class B is run by a thread while the inherited "run()" method in ClassB is run by another thread. The "createBitmap()" method implemented in ClassB should be run in a synchronized block inside the "run()" method.

My question is that I am not sure whether the newly defined class variable "outBmpB" in ClassB is safely accessed by the two threads. I am not sure the "synchronized (this)" block in the "run()" method would also "lock" the "outBmpB" variable defined just in ClassB ? If not, then could I add a "synchronized (this)" block in the "createBitmap()" implementation. e.g.

 protected Bitmap createBitmap() {
      synchronized (this) {
           outBmpB = ..... // create and process "outBmpB".
      }

      Bitmap bmp;
      bmp = ..... // create and process "bmp".
      return bmp;
 }

Thanks for any suggestion.

Lawrence

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

无力看清 2024-12-31 22:37:26

您不必同步它,因为它已经在超类中同步并且没有其他调用,但您应该同步。您的 createBitmap() 实现依赖于超类的实现细节。
在访问共享字段的每个点都进行同步。

由于这个事实,您当前的子类代码非常容易出错!

虽然通过 this 进行同步是有问题的,但通过其他人无法访问的私有对象进行同步是一个更好的主意。因此,您的代码不会被使用您的类对象的客户端破坏并在其上同步。

You don't have to synchronize it since it is already synchronized in super class and there are no other calls, but you should. Your implementation of createBitmap() relies on implementation details from the super class.
Do synchronization at every point you access your shared fields.

Due to this facts your current subclass' code is very error-prone!

While it is questionable to ever synchronize over this, it is a much better idea to synchronize over a private object nobody else can access. So your code cannot be broken by clients using your class objects and synchronize on it.

深海蓝天 2024-12-31 22:37:26

这不是“锁定”变量:你就是做不到。您的代码中确实有适当的锁。然而,“线程安全”意味着“对于任何合理的使用都是安全的”。由于更改 outBmpB 的方法是受保护的(即可供包成员和所有子项使用),因此最好显式同步。

作为一般规则,每次访问共享可变状态时,都必须确保持有锁。就你而言,你不确定。同时,Java 锁是可重入的,因此嵌套同步不会造成任何损害,而且可能会让您避免意外。

It's not about "locking" a variable: you just cannot do it. You do have a proper lock in your code. However, "thread safety" means, "It's safe for any reasonable usage". As your method changing outBmpB is protected—that is, available to the package members and all the children,—you're better off explicitly synchronizing.

As a general rule, every time you access shared mutable state, you must be sure you hold the lock. In your case, you are not sure. At the same time, Java locks are reentrant, so nested synchronization will not hurt—and will perhaps save you from surprises.

ぶ宁プ宁ぶ 2024-12-31 22:37:26

一般来说,最好锁定您正在使用的对象(在您的情况下为 bmpAoutBmpB),而不是锁定容器对象,除非您确实需要这样做(在这种情况下,同步方法会更好)。

根据您的具体情况,synchronized (this) 块将相互排除,所以是的,如果您不在任何地方调用 createBitmap(),它就会起作用。 else,因此在 createBitmap() 内部同步比在 run() 内部同步要好得多。

As a general idea, it's better to lock on the object you are using (bmpA and outBmpB in your case) than on the container object, unless you really need to do that (and in that case a synchronized method would be better).

As per your particular case, the synchronized (this) blocks will exclude each other and so yes, it would work if you don't call createBitmap() anywhere else, and so it's far better to synchronize inside createBitmap() than inside run().

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文