代码块上的同步

发布于 2024-10-19 09:20:12 字数 410 浏览 1 评论 0原文

我理解代码块的同步意味着特定代码一次只能由一个线程访问,即使许多线程正在等待访问该代码。

当我们在 run 方法中编写线程类时,我们通过给定对象来启动同步块。 例如

 class MyThread extends Thread{
   String sa;
   public MyThread(String s){
       sa=s;
   } 
   public void run(){
     synchronized(sa){
         if(sa.equals("notdone"){
             //do some thing on object
         }
     }
   }    
 }

,这里我们给同步块一个对象,这需要什么。我们如何为该特定代码块提供同步

I understood synchronization of a block of code means that particular code will be accessed by only one thread at time even many thread are waiting to access that.

when we are writing thread class in run method we starting synchronized block by giving object.
for example

 class MyThread extends Thread{
   String sa;
   public MyThread(String s){
       sa=s;
   } 
   public void run(){
     synchronized(sa){
         if(sa.equals("notdone"){
             //do some thing on object
         }
     }
   }    
 }

here we gave sa object to synchronized block what is the need of that.any how we are going to provide synchronization for that particular block of code

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

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

发布评论

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

评论(4

你对谁都笑 2024-10-26 09:20:12

我建议

  • 扩展 Runnable 而不是 Thread。
  • 不要锁定外部的 Runnable。相反,您应该调用一个可能使用内部锁的方法。
  • 字符串作为锁并不是一个好的选择。这意味着“hi”和“hi”将共享锁,但 new String(“hi”) 不会。
  • 如果您在线程的生命周期内锁定所有其他线程,为什么要使用多个线程?

I would suggest

  • extend Runnable rather than Thread.
  • don't lock in the Runnable on an external. Instead you should be calling a method which may use an internal lock.
  • String is not a good choice as a lock. It means that "hi" and "hi" will share a lock but new String("hi") will not.
  • if you are locking all other threads for the life of the thread, why are you using multiple threads?
℡Ms空城旧梦 2024-10-26 09:20:12

同步块的参数对象是块锁定的对象。
因此,所有具有相同对象的同步块排除彼此(以及该同一对象的所有同步方法)的同时执行。

因此,如果您有这个示例

class ExampleA extends Thread() {

    public ExampleA(Object l) {
       this.x = l;
    }

    private Object x;

    public void run() {
        synchronized(x) {     // <-- synchronized-block A
            // do something
        }
    }
}
class ExampleB extends Thread() {

    public ExampleB(Object l) {
       this.x = l;
    }

    private Object x;

    public void run() {
        synchronized(x) {     // <-- synchronized-block B
            // do something else
        }
    }
}

Object o1 = new Object();
Object o2 = new Object();

Thread eA1 = new ExampleA(o1);
Thread eA2 = new ExampleA(o2);
Thread eB1 = new ExampleB(o1);
Thread eB2 = new ExampleB(o2);

eA1.start(); eA2.start(); eB1.start(); eB2.start();

,现在我们有两个同步块(A 和 B,位于类 ExampleAExampleB 中),并且有两个锁对象(o1 和 o2)。

如果我们现在看一下同时执行,我们可以看到:

  • A1 可以与 A2 和 B2 并行执行,但不能与 B1 并行执行。
  • A2可以与A1和B1并行执行,但不能与B2并行执行。
  • B1可以与A2和B2并行执行,但不能与A1并行执行。
  • B2可以与A1和B1并行执行,但不能与A2并行执行。

因此,同步仅取决于参数对象,而不取决于同步块的选择。


在您的示例中,您使用的是:

 synchronized(sa){
     if(sa.equals("notdone"){
         //do some thing on object
     }
 }

这看起来像您在比较和工作时试图避免有人将您的实例变量 sa 更改为另一个字符串 - 但它并不能避免这种情况。

同步不适用于变量,它适用于对象 - 并且有问题的对象通常应该是包含变量的某个对象(您的当前 MyThread 对象)例,可通过 this 访问),或仅用于同步且不会更改的特殊对象。

正如 Peter Lawrey 所说,String 对象通常是同步锁的糟糕选择,因为所有相等的 String 文字都是同一个对象(即会排除彼此的同步块),而相等的非文字字符串(例如在运行时创建)则不是同步锁的最佳选择。相同的对象,因此不会排除其他此类对象或文字的同步块,这通常会导致微妙的错误。

The parameter object of the synchronized block is the object on which the block locks.
Thus all synchronized blocks with the same object are excluding each other's (and all synchronized methods' of this same object) simultaneous execution.

So if you have this example

class ExampleA extends Thread() {

    public ExampleA(Object l) {
       this.x = l;
    }

    private Object x;

    public void run() {
        synchronized(x) {     // <-- synchronized-block A
            // do something
        }
    }
}
class ExampleB extends Thread() {

    public ExampleB(Object l) {
       this.x = l;
    }

    private Object x;

    public void run() {
        synchronized(x) {     // <-- synchronized-block B
            // do something else
        }
    }
}

Object o1 = new Object();
Object o2 = new Object();

Thread eA1 = new ExampleA(o1);
Thread eA2 = new ExampleA(o2);
Thread eB1 = new ExampleB(o1);
Thread eB2 = new ExampleB(o2);

eA1.start(); eA2.start(); eB1.start(); eB2.start();

Now we have two synchronized blocks (A and B, in classes ExampleA and ExampleB), and we have two lock objects (o1 and o2).

If we now look at the simultaneous execution, we can see that:

  • A1 can be executed in parallel to A2 and B2, but not to B1.
  • A2 can be executed in parallel to A1 and B1, but not to B2.
  • B1 can be executed in parallel to A2 and B2, but not to A1.
  • B2 can be executed in parallel to A1 and B1, but not to A2.

Thus, the synchronization depends only on the parameter object, not on the choice of synchronization block.


In your example, you are using this:

 synchronized(sa){
     if(sa.equals("notdone"){
         //do some thing on object
     }
 }

This looks like you try to avoid that someone changes your instance variable sa to another string while you are comparing it and working - but it does not avoid this.

Synchronization does not work on a variable, it works on an object - and the object in question should usually be either some object which contains the variable (the current MyThread object in your case, reachable by this), or a special object used just for synchronization, and which is not changed.

As Peter Lawrey said, String objects usually are bad choices for synchronization locks, since all equal String literals are the same object (i.e. would exclude each other's synchronized blocks), while a equal non-literal string (e.g. created at runtime) is not the same object, and thus would not exclude synchronized blocks by other such objects or literals, which often leads to subtle bugs.

心的憧憬 2024-10-26 09:20:12

在此对象上同步的所有线程都将等待,直到当前线程完成其工作。例如,如果您对希望同步的集合进行读/写操作,这非常有用。所以你可以在setget方法中编写同步块。在这种情况下,如果一个线程正在读取信息,则并非所有其他想要读取或写入的线程都会等待。

All threads synchronized on this objects will wait until current thread finishes its work. This is useful for example if you have read/write operation to collection that your wish to synchronized. So you can write sychronized block in methods set and get. In this case if one thread is reading information not all other threads that want to either read or write will wait.

箹锭⒈辈孓 2024-10-26 09:20:12

那么问题是块同步的对象的功能是什么?

对象的所有实例都有所谓的监视器。在正常执行中,该监视器是无主的。

希望进入同步块的线程必须占有对象监视器。然而,一次只有一个线程可以拥有监视器。因此,如果监视器当前未被拥有,则线程将占有该监视器并执行同步代码块。线程离开同步块时释放监视器。

如果监视器当前被拥有,则需要进入同步块的线程必须等待监视器被释放,以便它可以获得所有权并进入同步块。可以有多个线程在等待,如果是这样,则只有一个线程将被授予监视器的所有权。剩下的就回去等待。

So the question is what is the function of the object that a block synchronizes on?

All instances of Object have what is called a monitor. In normal execution this monitor is unowned.

A thread wishing to enter a synchronized block must take possession of the object monitor. Only one thread can posses the monitor at a time, however. So, if the monitor is currently unowned, the thread takes possession and executes the synchronized block of code. The thread releases the monitor when it leaves the synchronized block.

If the monitor is currently owned, then the thread needing to enter the synchronized block must wait for the monitor to be freed so it can take ownership and enter the block. More than one thread can be waiting and if so, then only one will be given ownership of the monitor. The rest will go back to waiting.

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