Строковые литералы с одинаковым значением не сохраняют синхронизированную блокировку в контроллере - PullRequest
1 голос
/ 26 октября 2019

я знаю, что строковые литералы указывают на один и тот же объект и имеют одинаковые ссылки для одинаковых значений. так что это было как раз для моего случая синхронизации. Я проверил приведенный ниже код, и он пришел именно так, как я хотел. я хотел иметь блокировку для тех же строк и не иметь блокировки, когда строки были разными.

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");
    }

}

1 Ответ

1 голос
/ 26 октября 2019

Компилятор оптимизирует строки с одинаковым значением и делает их точно такими же экземплярами, когда они являются частью кода, как в:

if ("abc" == "abc")

Но если строка создается во время выполнения, как в вашемв случае, когда тест String анализируется с URL-адреса, он не оптимизируется таким же образом и является его собственным экземпляром.

Таким образом, http://localhost/test/name1, выполненный дважды, создаст два отдельных экземпляра строки, которые будутне сравнивать ==, а это означает, что синхронизация с ним не даст ожидаемых результатов.

Кажется, что вы пытаетесь сделать обработку одних и тех же "тестовых" значений синхронной, но допускаете, чтобы разные тестовые значенияобрабатывать асинхронно. Если это так, то вы можете сделать что-то вроде сохранения карты значений, которые обрабатываются, где «тестовое» значение является ключом, а экземпляр Object сохраняется как значение, используемое в качестве мьютекса. Затем выполните синхронизацию с мьютексом после его поиска.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...