Должен ли я всегда делать свой Java-код потокобезопасным или по соображениям производительности делать это только при необходимости? - PullRequest
23 голосов
/ 24 октября 2008

Если я создаю классы, которые в данный момент используются только в одном потоке, должен ли я сделать их поточно-ориентированными, даже если в данный момент мне это не нужно? Может случиться так, что позже я использую этот класс в нескольких потоках, и в то время я мог получить условия гонки и мне было бы трудно найти их, если я не сделал класс потокобезопасным с самого начала. Или я должен сделать класс не потокобезопасным, для лучшей производительности? Но преждевременная оптимизация - это зло.

Другой вопрос: должен ли я сделать свои классы поточно-ориентированными, если это необходимо (если они используются в нескольких потоках, в противном случае нет), или мне следует оптимизировать эту проблему, если это необходимо (если я вижу, что синхронизация израсходует важную часть времени обработки)

Если я выберу один из обоих способов, есть ли способы уменьшить недостатки? Или существует третья возможность, которую я должен использовать?

РЕДАКТИРОВАТЬ : Я привел причину, по которой этот вопрос возник у меня в голове. В нашей компании мы написали очень простое управление пользователями, которое записывает данные в файлы свойств. Я использовал его в веб-приложении, и после некоторой работы над ним я получил странные ошибки, из-за которых руководство пользователя забыло о свойствах пользователей (включая имя и пароль) и ролях. Это было очень раздражающим, но не всегда воспроизводимым, так что я думаю, что это было состояние гонки. Поскольку я синхронизировал все методы чтения и записи с / на диск, проблема исчезла. Так что я подумал, что, возможно, я мог бы избежать всех хлопот, если бы мы сначала написали класс с синхронизацией?

РЕДАКТИРОВАТЬ 2 : просматривая советы Pragmatic Programmer, я увидел совет № 41: Всегда разрабатывать для параллелизма. Это не говорит о том, что весь код должен быть потокобезопасным, но говорит, что дизайн должен учитывать параллелизм.

Ответы [ 13 ]

0 голосов
/ 24 октября 2008

«Всегда» - очень опасное слово в разработке программного обеспечения ... варианты, подобные этому, «всегда» ситуативны.

0 голосов
/ 24 октября 2008

Разрабатывайте отдельно классы для использования из нескольких потоков и документируйте другие для использования только из одного потока.

Однопоточные с ними намного проще работать.

Разделение многопоточной логики помогает сделать синхронизацию правильной.

0 голосов
/ 24 октября 2008

Если вы хотите следить за тем, что Sun делала в Java API, вы можете взглянуть на классы коллекций. Многие распространенные классы коллекций не являются поточно-ориентированными, но имеют поточно-ориентированные аналоги. По словам Джона Скита (см. Комментарии), многие из классов Java изначально были поточно-ориентированными, но не приносили пользы разработчикам, поэтому некоторые классы теперь имеют две версии - одна поточно-ориентированная, а другая не поточно-безопасная.

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

...