Java 线程内在锁

Java 线程内在锁,java,multithreading,Java,Multithreading,当我们谈论内在锁时,我们指的是我们请求锁的对象 还是同步方法 锁定是在对象上还是在其同步方法上 我糊涂了 同步方法锁定对象上的方法 synchronized void methodA () { .... } 在某种程度上等同于 void methodA () { synchronized (this) { .... } } 对象上有内部锁: class A { public synchronized void method1(){...}

当我们谈论内在锁时,我们指的是我们请求锁的对象 还是同步方法

锁定是在对象上还是在其同步方法上


我糊涂了

同步方法锁定对象上的方法

synchronized void methodA () {
    ....    
}
在某种程度上等同于

void methodA () {
    synchronized (this) {
        ....
    }
}

对象上有内部锁:

class A
{
   public synchronized void method1(){...}
   public synchronized void method2(){...}
}

如果线程A位于方法1中,则线程B无法进入方法2。

锁是对象的一部分。每个对象都有一个,可以通过两种方式锁定:

  • 在类的实例方法上使用
    synchronized
    修饰符锁定关联对象
  • 使用
    同步(对象){}
  • 类似地,您可以锁定对象的类而不是对象本身(为了理解
    synchronized
    修饰符和
    static
    方法,请单独提及):

  • 在类的静态方法上使用
    synchronized
    修饰符锁定类
  • 使用
    synchronized(clazz){}
    块,其中
    clazz
    是对象的类

  • 锁定对象。在Java中,每个对象都是一个

    在Java中,每次使用synchronized关键字都会隐含一个内在锁

    synchronized关键字的每次使用都与两种类型的内在锁中的一种相关联:

    附加到单个对象的“实例锁”

    附加到类的“静态锁”

    如果一个方法被声明为synchronized,那么它在被调用时将根据它是实例方法还是静态方法获取实例锁或静态锁

    这两种类型的锁具有相似的行为,但彼此完全独立

    获取实例锁只会阻止其他线程调用同步实例方法;它不会阻止其他线程调用非同步方法,也不会阻止它们调用静态同步方法

    类似地,获取静态锁只会阻止其他线程调用静态同步方法;它不会阻止其他线程调用非同步方法,也不会阻止它们调用同步实例方法

    在方法头之外,synchronized(this)获取实例锁

    静态锁可以通过两种方式在方法头之外获取:

    已同步(Blah.class),使用类文本

    已同步(this.getClass()),如果对象可用

    private int count=0;
    
    private int count = 0;
    public synchronized void countFunc(){
            count++;
        }
    Thread t1 = new Thread(new Runnable(){
                public void run(){
                for(int i=0;i<1000;i++){
                    countFunc();
                    }}});
            Thread t2 = new Thread(new Runnable(){
                public void run(){
                for(int i=0;i<1000;i++){
                    countFunc();
                }}});
    
    公共同步的void countFunc(){ 计数++; } 线程t1=新线程(新的可运行线程(){ 公开募捐{
    对于(inti=0;i而言,锁定在对象上

    查看上的java教程页面


    每个对象都有一个与之关联的内在锁。按照惯例,需要以独占和一致方式访问对象字段的线程必须在访问对象字段之前获取该对象的内在锁,然后在处理完这些字段后释放该内在锁。线程被称为在获取期间拥有该内在锁打开锁,然后松开锁

    只要一个线程拥有一个内在锁,就没有其他线程可以获得相同的锁。当另一个线程试图获得锁时,它将阻塞

    使用内部锁的两种方法:

  • 同步方法:

    当线程调用
    synchronized
    方法时,它会自动获取该方法对象的内在锁,并在该方法返回时释放它

    e、 g

  • 同步语句

    synchronized
    方法不同,
    synchronized
    语句必须指定提供内部锁的对象

    public int getCounter(){
        synchronized(this){
            return counter;
        }
    }
    
    完整示例:

    public class SynchronizedDemo{
    private int counter = 0;
    
    public SynchronizedDemo(){
    
    }
    public synchronized void incrementCounter(){
        ++counter;
    }
    public int getCounter(){
        synchronized(this){
            return counter;
        }
    }
    public static void main(String[] args){
        SynchronizedDemo object = new SynchronizedDemo();
        for ( int i=0; i < 5; i++){
            Thread t = new Thread(new SimpleRunnable(object));
            t.start();
        }           
    }
    }
    class SimpleRunnable implements Runnable{
    private SynchronizedDemo object;
    
    public SimpleRunnable(SynchronizedDemo obj){
        this.object = obj;
    }
    public void run(){
        object.incrementCounter();
        System.out.println("Counter:"+object.getCounter());
    }
    }
    
    公共类同步数据{
    专用整数计数器=0;
    公共同步demo(){
    }
    公共同步的无效增量计数器(){
    ++计数器;
    }
    公共int getCounter(){
    已同步(此){
    返回计数器;
    }
    }
    公共静态void main(字符串[]args){
    SynchronizedDemo对象=新的SynchronizedDemo();
    对于(int i=0;i<5;i++){
    线程t=新线程(新SimpleRunTable(对象));
    t、 start();
    }           
    }
    }
    类SimpleRunnable实现可运行{
    私有同步数据对象;
    公共SimpleRunnable(SynchronizedDemo obj){
    this.object=obj;
    }
    公开募捐{
    object.incrementCounter();
    System.out.println(“计数器:+object.getCounter());
    }
    }
    

  • 注意:编写此示例只是为了展示使用内部锁的不同方式。对于这种类型的用例,使用for计数器变量是正确的方法。

    每个对象都有一个内部锁。这两个语句是等效的,因为它们都在包含methodA()的对象的内部锁上同步。向不了解同步方法的人解释同步语句不是一个好主意。这让我更加困惑。我希望,最后一行允许我+10。:)
    public class SynchronizedDemo{
    private int counter = 0;
    
    public SynchronizedDemo(){
    
    }
    public synchronized void incrementCounter(){
        ++counter;
    }
    public int getCounter(){
        synchronized(this){
            return counter;
        }
    }
    public static void main(String[] args){
        SynchronizedDemo object = new SynchronizedDemo();
        for ( int i=0; i < 5; i++){
            Thread t = new Thread(new SimpleRunnable(object));
            t.start();
        }           
    }
    }
    class SimpleRunnable implements Runnable{
    private SynchronizedDemo object;
    
    public SimpleRunnable(SynchronizedDemo obj){
        this.object = obj;
    }
    public void run(){
        object.incrementCounter();
        System.out.println("Counter:"+object.getCounter());
    }
    }