/ / Чи потрібно мені синхронізувати і метод, і об'єкт - java, синхронізація

Чи потрібно синхронізувати як метод, так і об'єкт - java, синхронізацію

Отже, у мене є такий список, до якого можна отримати доступ з декількох потоків:

ArrayList<String> listOfString = Collections.synchronizedList(new ArrayList<String>());

Я знаю, що коли я повторюю список, я повинен синхронізуватися так:

synchronized(listOfString)
{
for(String s : listOfString) System.out.println(s);

listOfString.clear();
}

А як бути, якщо я хочу щось видалити, чи роблю це:

public void removeString(String s)
{
listOfString.remove(s);
}

або це:

public synchronized void removeString(String s)
{
listOfString.remove(s);
}

Відповіді:

7 для відповіді № 1

Як ви вже сказали, список уже синхронізований, так що ваш removeString методом не потрібно synchronized теж

Зауважте, що якщо один із ваших методів міститьнеатомна операція (скажімо, ви хочете перевірити, чи містить ваш список, а потім змінити відповідний список), можливо, вам доведеться додати ще один шар синхронізації.

Нарешті, ви, схоже, не помітили, що цей метод:

public synchronized void removeString(String s)

синхронізується на іншому блокуванні (синхронізується на this). Отже, повернувшись до прикладу, який я наводив вище, ви напишете це:

public void someMethod() {
synchronized(listOfString) { //use the same lock!
if(listOfString.size() == 123) {
listOfString.add("lucky day");
}
}
}