Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/350.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.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_String_Synchronization - Fatal编程技术网

Java 同步依赖于字符串初始化

Java 同步依赖于字符串初始化,java,string,synchronization,Java,String,Synchronization,我正在尝试使用字符串对象作为锁(是的,我知道不建议使用它-这只是为了理解锁) 在创建锁时初始化锁时,所有操作都正常: 代码: 日志: [线程555时间:2015/02/18 18:16:03] [线程555睡得很好!时间:2015/02/18 18:17:43] [线程557时间:2015/02/18 18:17:43] [线程557睡得很好!时间:2015/02/18:19:23] [线程556时间:2015/02/18 18:19:23] [线程556睡得很好!时间:2015/02/18 1

我正在尝试使用字符串对象作为锁(是的,我知道不建议使用它-这只是为了理解锁)

在创建锁时初始化锁时,所有操作都正常:

代码:

日志:

[线程555时间:2015/02/18 18:16:03]
[线程555睡得很好!时间:2015/02/18 18:17:43]
[线程557时间:2015/02/18 18:17:43]
[线程557睡得很好!时间:2015/02/18:19:23]
[线程556时间:2015/02/18 18:19:23]
[线程556睡得很好!时间:2015/02/18 18:21:03]

但是当我在方法中初始化实例成员锁时,就好像同步不起作用一样

代码:

日志:

[线程555时间:2015/02/18 19:17:35]
[线程556时间:2015/02/18 19:17:40]
[线程556时间:2015/02/18 19:17:41]
[线程557时间:2015/02/18 19:17:44]
[线程560时间:2015/02/18 19:17:48]
[线程555睡得很好!时间:2015/02/18 19:19:15]
[线程556睡得很好!时间:2015/02/18 19:19:20]
[线程556睡得很好!时间:2015/02/18 19:19:21]
[线程557睡得很好!时间:2015/02/18 19:19:24]
[线程560睡得很好!时间:2015/02/18 19:19:28]

我不明白我启动目标的地方是什么地方?更多-它是一个字符串对象,所以无论如何它不应该是同一个引用?我错过了什么

编辑:是的,我不小心交换了代码。。当您多次收到“您的帖子似乎包含未正确格式化为代码的代码”,然后发现这是由于日志行引起的:|将修复交换

(您可能交换了代码片段)

我认为你错过了一个重要的方面。如果不使用字段
作为锁,则将锁分配给实例。或如手册中所述:

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

因此,在您的第二个问题(问题代码片段中的第一个问题)中,您创建了一个新对象,即:

lock = new String("hello");
然后锁定该对象。这意味着每个线程都有一个它锁定的不同实例。所以根本就没有同步

示例:假设您有两个线程
t1
t2
。首先,我们运行线程1的一部分。线程一调用该方法并创建一个
字符串
实例,其值为
“hello”
。所以内存看起来像:

+------+                    +---------------+
|Action| <------------------+ thread memory |
+------+      +-------+     +---------------+
| lock------->|String |     
+------+      +-------+
              |"hello"|
              +-------+
现在线程
t2
进入。而
t2
做的第一件事就是创建一个新对象:

+------+                    +----------------+
|Action| <------------------+ thread2 memory |   (old object)
+------+      +-------+     +----------------+   +-------+
| lock------->|String |                          |String | &
+------+      +-------+                          +-------+
              |"hello"|                          |"hello"|
              +-------+                          +-------+
+----++----------------+
|动作| |串| |串|&
+------+      +-------+                          +-------+
|“你好”| |“你好”|
+-------+                          +-------+
因此,新对象未锁定,线程
t2
可以继续执行


然而,有可能您的代码确实会部分锁定。例如,线程
t1
可能首先创建一个对象,然后设置
Action
的字段,然后挂起。然后
t2
变为活动状态,同时创建一个对象,设置
操作的
字段,因此两个线程都以相同的对象结束,但这种可能性不大



最后要注意的是,使用“
字符串”
作为锁“
没有问题。首先,不要将
字符串
用作锁,应该将其视为“锁定”字符串。因此,虚拟机只是将信息附加到它锁定的对象上。因此,没有好的或坏的对象可以被锁定。

你所说的“当我初始化方法时”是什么意思。您可以发布为这两种情况创建和启动线程的代码吗?在第一个示例中,您的
myAction
方法每次都创建单独的锁对象,因此我不会阻止其他线程使用它,因为使用此方法时,所有线程都将有新锁。在第二种情况下,只有一个线程能够进入synchronized块,因为在调用方法之前,将只存在一个创建的锁。换句话说,您可以从第一个代码示例中删除
lock
和同步机制,您应该会得到相同的结果。@Moria:您是否意外地交换了这两个代码片段?您也可以执行
Object lock=new Object()
。它避免了字符串的“不推荐”部分。@davidermann:老实说,我不明白为什么不建议将字符串作为
对象。既然
字符串是不可变的,它确实不是很常见,但有理由不这样做……但我不明白的是:1)我从哪里开始有什么关系?成员不是静态的,在这两种情况下t1和t2都有各自“自己的”锁。2) 这怎么可能是每一个都有不同的字符串呢?如果它们使用相同的字符串值,那么应该引用内存中的相同对象,不是吗?谢谢关键是每次调用该方法时都要实例化一个新对象。因此,不是所有线程共享一个对象,而是每个线程生成自己的对象。
+------+                    +---------------+
|Action| <------------------+ thread memory |
+------+      +-------+     +---------------+
| lock------->|String |     
+------+      +-------+
              |"hello"|
              +-------+
+------+                    +---------------+
|Action| <------------------+ thread memory |
+------+      +-------+     +---------------+
| lock------->|String | &     
+------+      +-------+
              |"hello"|
              +-------+
+------+                    +----------------+
|Action| <------------------+ thread2 memory |   (old object)
+------+      +-------+     +----------------+   +-------+
| lock------->|String |                          |String | &
+------+      +-------+                          +-------+
              |"hello"|                          |"hello"|
              +-------+                          +-------+