Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/371.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
java中的同步关键字和静态类_Java_Multithreading_Synchronize - Fatal编程技术网

java中的同步关键字和静态类

java中的同步关键字和静态类,java,multithreading,synchronize,Java,Multithreading,Synchronize,我在读一本线程教程,它最初来自(我相信)IBMdeveloperWorks站点。在这篇文章中,他们讨论了synchronized关键字,以及同步代码块是如何被实际对象而不是代码块本身锁定的 例如,在下面的代码中,作者指出,即使静态类“Thingie”的setLastAccess方法被列为synchronized,下面定义的两个线程也可以同时调用setLastAccess,因为它们对Thingie使用不同的值。但是如果东西是静态的,这不意味着它们使用相同的值吗 变量名是否只需要不同,即使它们引用的

我在读一本线程教程,它最初来自(我相信)IBMdeveloperWorks站点。在这篇文章中,他们讨论了synchronized关键字,以及同步代码块是如何被实际对象而不是代码块本身锁定的

例如,在下面的代码中,作者指出,即使静态类“
Thingie
”的
setLastAccess
方法被列为synchronized,下面定义的两个线程也可以同时调用
setLastAccess
,因为它们对Thingie使用不同的值。但是如果东西是静态的,这不意味着它们使用相同的值吗

变量名是否只需要不同,即使它们引用的是同一个对象

public class SyncExample {
    public static class Thingie {
        private Date lastAccess;
        public synchronized void setLastAccess(Date date) {
            this.lastAccess = date;
        }
    }
    public static class MyThread extends Thread {
        private Thingie thingie;
        public MyThread(Thingie thingie) {
            this.thingie = thingie;
        }
        public void run() {
            thingie.setLastAccess(new Date());
        }
    }
    public static void main() {
        Thingie thingie1 = new Thingie(),
        thingie2 = new Thingie();
        new MyThread(thingie1).start();
        new MyThread(thingie2).start();
    }
} 

您将静态方法与静态类混淆。如果
setLastAccess
是一个静态方法,那么如果它被标记为
synchronized
,它将锁定
ClassLoader
中的
Class
实例——每个加载程序只有一个实例。如果该方法是静态和同步的,那么线程将锁定在同一对象上

但是,在您的示例中,
Thingie
类被标记为静态,而不是方法。类上的static关键字表示
Thingie
未绑定到外部
SyncExample
类——这并不意味着只有一个
Thingie
实例,也不影响同步。因此,在您的示例中,当
setLastAccess
标记为
synchronized
时,它将锁定类
Thingie
this
)的实例。由于存在两个实例(
thingie1
thingie2
),因此锁位于不同的对象上。显然,如果两个线程都传入
thingie1
,那么它们都将锁定在同一个对象上

以下是一些阅读材料:


您将静态方法与静态类混淆。如果
setLastAccess
是一个静态方法,那么如果它被标记为
synchronized
,它将锁定
ClassLoader
中的
Class
实例——每个加载程序只有一个实例。如果该方法是静态和同步的,那么线程将锁定在同一对象上

但是,在您的示例中,
Thingie
类被标记为静态,而不是方法。类上的static关键字表示
Thingie
未绑定到外部
SyncExample
类——这并不意味着只有一个
Thingie
实例,也不影响同步。因此,在您的示例中,当
setLastAccess
标记为
synchronized
时,它将锁定类
Thingie
this
)的实例。由于存在两个实例(
thingie1
thingie2
),因此锁位于不同的对象上。显然,如果两个线程都传入
thingie1
,那么它们都将锁定在同一个对象上

以下是一些阅读材料:

此代码:

class SomeClass {
    public synchronized void setLastAccess(Date date) {
    }
}
同:

class SomeClass {
    public void setLastAccess(Date date) {
        synchronized(this) {
        }
    }
}
class SomeClass {
    public static void setLastAccess(Date date) {
        synchronized(SomeClass.class) {
        }
    }
}
该代码:

class SomeClass {
    public static synchronized void setLastAccess(Date date) {
    }
}
同:

class SomeClass {
    public void setLastAccess(Date date) {
        synchronized(this) {
        }
    }
}
class SomeClass {
    public static void setLastAccess(Date date) {
        synchronized(SomeClass.class) {
        }
    }
}
此代码:

class SomeClass {
    public synchronized void setLastAccess(Date date) {
    }
}
同:

class SomeClass {
    public void setLastAccess(Date date) {
        synchronized(this) {
        }
    }
}
class SomeClass {
    public static void setLastAccess(Date date) {
        synchronized(SomeClass.class) {
        }
    }
}
该代码:

class SomeClass {
    public static synchronized void setLastAccess(Date date) {
    }
}
同:

class SomeClass {
    public void setLastAccess(Date date) {
        synchronized(this) {
        }
    }
}
class SomeClass {
    public static void setLastAccess(Date date) {
        synchronized(SomeClass.class) {
        }
    }
}

如果同步方法是实例方法,则对每个对象执行锁定。因此,如果您有两个对象obj1和obj2,它们可以在自己的实例被锁定的情况下执行方法


如果一个静态方法是同步的,那么锁定就在类对象上完成。因此,在执行第一个静态同步方法时,无法执行该方法以及任何其他静态方法。

如果同步方法是实例方法,则对每个对象执行锁定。因此,如果您有两个对象obj1和obj2,它们可以在自己的实例被锁定的情况下执行方法


如果一个静态方法是同步的,那么锁定就在类对象上完成。因此,在执行第一个静态同步方法时,无法执行该方法以及任何其他静态方法。

我确信它不依赖于变量的名称。同步是对实际对象的调用,而不是对变量的调用。我的回答对@larryq有帮助吗?如果是这样的话,请接受它。我确信它不依赖于变量的名称。同步是对实际对象的调用,而不是对变量的调用。我的回答对@larryq有帮助吗?如果是的话,请接受。我感谢你的解释。然而,假设Thingie是一个静态类,那么是否可以有两个实例(thingie1和thingie2)?如果不是,这是否意味着对setLastAccess()的两个(同步)调用是从同一Thingie实例调用的?不确定您是否阅读了我的答案@larryq。
static
关键字并不表示单个实例。阅读我答案中的第二段和上面的“嵌套类”链接。格雷-非常感谢您的澄清和链接。我之前对嵌套静态类表示什么的误解。我认为这意味着它是外部类的一个静态成员(虽然是一个类),因此不能直接实例化——或者至少,这样做只会返回一个绑定到外部类的实例。我错了。我道歉,格雷,你现在得到了照顾。我感谢你的解释。然而,假设Thingie是一个静态类,那么是否可以有两个实例(thingie1和thingie2)?如果不是,这是否意味着对setLastAccess()的两个(同步)调用是从同一Thingie实例调用的?不确定您是否阅读了我的答案@larryq。
static
关键字并不表示单个实例。阅读我答案中的第二段和上面的“嵌套类”链接。格雷-非常感谢您的澄清和链接。我之前对嵌套静态类repr的误解