具有相同值的字符串文字不会在控制器中保持同步锁定
String literals with same value doesn't keep a synchronized lock in controller
我知道字符串文字指向同一个对象并且对相同的值具有相同的引用。所以它正好适合我的同步情况。我测试了下面的代码,结果正是我想要的。我想在相同的字符串上锁定并且在字符串不同时没有锁定。
public class SampleThread extends Thread {
String lock;
public SampleThread(String s) {
this.lock = s;
}
@Override
public void run() {
long id = this.getId();
synchronized (lock) {
for (int i = 0; i < 1000; i++) {
System.out.println("thread with id: "+id);
}
}
}
public static void main(String[] args) {
SampleThread s1 = new SampleThread("mina");
SampleThread s2 = new SampleThread("mina");
s1.start();
s2.start();
}
}
第一个线程完成,然后第二个线程开始。我在我的控制器中放置了相同的代码,但对于相同的 literals.two 请求进入块而不考虑字符串锁定,这不起作用。有没有什么办法解决这一问题?这是我测试过的示例,但不起作用。
@RequestMapping("/test/{name}")
public void test(@PathVariable("name") String test) throws InterruptedException {
String a = test;
synchronized (String.valueOf(a)) {
System.out.println("first");
TimeUnit.SECONDS.sleep(4);
System.out.println("finish");
}
}
当它们是代码的一部分时,编译器将优化相同值的字符串并使它们成为完全相同的实例,如:
if ("abc" == "abc")
但是如果字符串是在运行时创建的,就像您的情况一样,其中字符串测试是从 URL 解析的,那么它不会以相同的方式进行优化,而是它自己的实例。
因此 http://localhost/test/name1 执行两次将创建两个不会比较的单独字符串实例 == 并且这意味着对其进行同步不会给出您期望的结果。
您似乎在尝试同步处理相同的 "test" 值,但允许异步处理不同的测试值。如果是这种情况,那么您可以做一些事情,例如保留正在处理的值的映射,其中 "test" 值是键,并且 Object 的实例存储为用作互斥锁的值。然后在查找互斥体上同步。
我知道字符串文字指向同一个对象并且对相同的值具有相同的引用。所以它正好适合我的同步情况。我测试了下面的代码,结果正是我想要的。我想在相同的字符串上锁定并且在字符串不同时没有锁定。
public class SampleThread extends Thread {
String lock;
public SampleThread(String s) {
this.lock = s;
}
@Override
public void run() {
long id = this.getId();
synchronized (lock) {
for (int i = 0; i < 1000; i++) {
System.out.println("thread with id: "+id);
}
}
}
public static void main(String[] args) {
SampleThread s1 = new SampleThread("mina");
SampleThread s2 = new SampleThread("mina");
s1.start();
s2.start();
}
}
第一个线程完成,然后第二个线程开始。我在我的控制器中放置了相同的代码,但对于相同的 literals.two 请求进入块而不考虑字符串锁定,这不起作用。有没有什么办法解决这一问题?这是我测试过的示例,但不起作用。
@RequestMapping("/test/{name}")
public void test(@PathVariable("name") String test) throws InterruptedException {
String a = test;
synchronized (String.valueOf(a)) {
System.out.println("first");
TimeUnit.SECONDS.sleep(4);
System.out.println("finish");
}
}
当它们是代码的一部分时,编译器将优化相同值的字符串并使它们成为完全相同的实例,如:
if ("abc" == "abc")
但是如果字符串是在运行时创建的,就像您的情况一样,其中字符串测试是从 URL 解析的,那么它不会以相同的方式进行优化,而是它自己的实例。
因此 http://localhost/test/name1 执行两次将创建两个不会比较的单独字符串实例 == 并且这意味着对其进行同步不会给出您期望的结果。
您似乎在尝试同步处理相同的 "test" 值,但允许异步处理不同的测试值。如果是这种情况,那么您可以做一些事情,例如保留正在处理的值的映射,其中 "test" 值是键,并且 Object 的实例存储为用作互斥锁的值。然后在查找互斥体上同步。