简体   繁体   English

同步块上的Java线程锁定

[英]Java Thread lock on synchronized blocks

I am learning synchronized blocks with locks.I want to know the difference between this lock and some third party lock that provided in the program. 我正在学习带锁的同步块。我想知道此锁与程序中提供的某些第三方锁之间的区别。

public class NewThread extends Thread {
StringBuffer sb;
NewThread(StringBuffer sb){
    this.sb=sb;
}
public void run(){
    synchronized(this.sb){
        for(int i=0;i<1000;i++){
            System.out.print(sb);
               try{
             Thread.sleep(5*60);
        }
        catch(Exception e){}
        }
       char c = this.sb.charAt(0);
       this.sb.setCharAt(0, ++c);
    }
}
public static void main(String[] args){
    StringBuffer sb=new StringBuffer("A");
    NewThread nt=new NewThread(sb);
    NewThread nt1=new NewThread(sb);
    NewThread nt2=new NewThread(sb);
    nt.start();
    nt1.start();
    nt2.start();
}

} }

If i am going to put 如果我要放

public void run(){
    synchronized(this){
        for(int i=0;i<1000;i++){
            System.out.print(sb);
               try{
             Thread.sleep(5*60);
        }
        catch(Exception e){}
        }
       char c = this.sb.charAt(0);
       this.sb.setCharAt(0, ++c);
    }
}

here in the above run method i gave this in the synchronized block ...i want the difference between them 在上面的运行方法中,我在同步块中给出了这个...我想要它们之间的区别

i am having one more question ,if we are giving a lock object in synchronized block and we are not using that object inside that block then does we observe any thing specific compared to normal block 我还有一个问题,如果我们在同步块中提供锁对象,而我们不在该块中使用该对象,那么与普通块相比,我们是否观察到任何特定的东西

If you have concurrent development experience with general OS API, eg pthread library in Linux, you may have a knowledge that we should use lock or other data structure to synchronize processes/threads accessing critical section(where shared object may be modified). 如果您具有通用OS API的并发开发经验,例如Linux中的pthread库,您可能已经知道我们应该使用锁或其他数据结构来同步访问关键部分(可以修改共享对象)的进程/线程。

Java use lock to implement synchronization block. Java使用锁来实现同步块。 Synchronization block is a kind of mechanism(called monitor in operating system) encapsulating tedious operation related to lock. 同步块是一种封装与锁定有关的繁琐操作的机制(在操作系统中称为监视器)。 Each object has a lock in java. 每个对象在java中都有一个锁。 When synchronized, lock in shared object is locked at first(also we can say other process require lock of the shared object). 同步时,首先锁定共享库中的锁(也可以说其他进程需要锁定共享库)。 If some thread fail to acquire the lock, that means some other thread is now holding the lock, it must wait until other thread release the lock and re-acquire again until it hold the lock and then enter the critical section. 如果某个线程无法获取该锁,则意味着其他线程现在正在持有该锁,它必须等到其他线程释放该锁并再次重新获取,直到它持有该锁,然后进入关键部分。

The first code snippet use lock in instance of StringBuffer, ie sb, each thread will try to get sb's lock(invoke lock_of_sb.lock() before running the code. Only that acquired sb's lock successfully can eventually execute the code. 第一个代码段使用StringBuffer实例中的锁,即sb,每个线程将在运行代码之前尝试获取sb的锁(调用lock_of_sb.lock()。只有成功获得sb的锁才能最终执行代码。

As to the second code, which is equivalent to 至于第二个代码,相当于

public synchronized void run(){
  for(int i=0;i<1000;i++){
      System.out.print(sb);
         try{
       Thread.sleep(5*60);
  }
  catch(Exception e){}
  }
  char c = this.sb.charAt(0);
  this.sb.setCharAt(0, ++c);
}

I don't think it behaves as you expected. 我认为它的行为不符合您的预期。 It acquire lock in this object, however, this object is never shared. 它获取此对象的锁定,但是,此对象永远不会共享。 So the shared sb is exposed into the critical section without any synchronization. 因此,共享的sb暴露在关键部分,而没有任何同步。

The link will give you another working way to achieve synchronization. 该链接将为您提供实现同步的另一种工作方式。 How to synchronize static method in java Although the question itself is about static method, it also works well to instance member method. 如何在Java中同步静态方法尽管问题本身是关于静态方法的,但它也适用于实例成员方法。

Others have already answered but to add my 2 cents, 其他人已经回答了,但要加上我的2美分,

a) First example is ok, in the sense that the synchronized keyword is guarding the StringBuffer Threads are sharing one lock. a)第一个示例是正确的,在某种意义上, synchronized关键字正在保护StringBuffer线程共享一个锁。

b) Second example is not ok. b)第二个例子不好。 You are giving each thread a different lock. 您给每个线程一个不同的锁。 In effect, it doesn't have any effect (in fact, modern Java compilers remove such locks completely). 实际上,它没有任何作用(实际上,现代Java编译器会完全删除此类锁)。 Locks are meaningful if more than one thread uses it. 如果有多个线程使用锁,则锁是有意义的。

You could think of it like this: 您可以这样想:
If you share a bathroom, you better have one lock for the bathroom (like its door key). 如果您共用一间浴室,则最好为浴室配备一把锁(如门钥匙)。 If you'd ask everybody to lock their own, individual iPhone before using the bathroom, it would be surely useless. 如果您要求所有人在使用浴室之前将自己的个人iPhone锁定,那肯定是没有用的。 Note that the shared look does not need to be the door key. 请注意,共享外观不必是门钥匙。 You might as well as pick one iPhone and use it as the bathroom "key" (everybody has to lock that iPhone before using the bathroom, and only the guy who locked it may unlock it). 您不妨选择一部iPhone并将其用作浴室的“钥匙”(每个人都必须在使用浴室之前锁定 iPhone,只有锁定它的人才能解锁它)。 In real-life that sounds absurd, but that's pretty much what we do with mutexes. 在现实生活中,这听起来很荒谬,但这几乎就是我们对互斥锁所做的事情。

c) The second example can be considered buggy, but in practice, you won't see the effect of the race condition. c)第二个示例可以认为是越野车,但是在实践中,您不会看到竞争条件的影响。 This is because StringBuffer synchronizes internally. 这是因为StringBuffer内部进行同步。 If you use StringBuilder instead, you might be able to see race conditions (depends on runtime conditions). 如果改用StringBuilder ,则可能会看到竞争条件(取决于运行时条件)。

In Java each object can be used as Mutex (See Mutual Exclusion ). 在Java中,每个对象都可以用作互斥对象(请参见互斥 )。 This means that only one thing can synchronize on an object at any time, which object you use is generally irreverent although it should be as specific as possible. 这意味着任何时候任何事物都只能在一个对象上同步,您使用的那个对象通常是无关紧要的,尽管它应该尽可能具体。 For example if multiple threads are accessing a List, you should synchronized on that list rather than on the entire object (this) so that other things that need something else in the object may access it. 例如,如果有多个线程正在访问列表,则应在该列表上同步,而不是在整个对象(this)上同步,以便该对象中需要其他内容的其他事物也可以访问它。

I think the article on mutual exclusion may help to clarify the matter. 我认为有关互斥的文章可能有助于澄清这一问题。 In essence, only one thread may get the key to a "lock" -- that lock is what is inside synchronized. 本质上,只有一个线程可以获取“锁”的密钥-该锁是内部同步的。 So long as everything accessing your resource requests the lock on the SAME object, you are protected. 只要访问资源的所有请求都请求锁定SAME对象,就可以保护您。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM