Как неудобство String стало преимуществом в качестве String-builder. я имею в виду, что я понял, что строка неизменяема, потому что если предполагается, что существует пять объектов String, и если есть изменение в одном объекте, то оно будет отражать во всех и может вызвать ошибки времени выполнения и после этого String-Buffer является изменяемым, но по крайней мере это синхронизированный один поток во время. все идет хорошо, и, наконец, теперь String-builder изменен с несколькими потоками для доступа. это так сложно использовать? как программист может это сделать.Как String Builder управляет доступом нескольких потоков к одному объекту и изменчивости?
ответ
StringBuffer
синхронизирован, что означает, что весь его метода syncrhonized
, так что его можно безопасно использовать в многопоточной среде, то есть несколько потоков могут изменять и извлекать содержимое из StringBuffer
экземпляра безопасно.
Цена этой способности заключается в том, что, когда 2 потока обращаются к экземпляру StringBuffer
, в то же время второй поток блокируется до тех пор, пока первый поток не будет иметь дело с буфером. Это означает, что ваша многопоточная система становится лицом однопоточно в течение этого периода времени. Если такие ситуации случаются часто, производительность вашей системы может быть намного ниже, чем может быть без блокировок.
StringBuilder
не синхронизирован. Это означает, что если 2 потока меняют свое состояние одновременно, результат непредсказуем. Таким образом, вы должны сами управлять своей политикой доступа, синхронизируя методы, которые предоставляют доступ к instanceo вашего StringBuilder
, или избегая многопоточного доступа, например, используя по-настоящему неизменяемые объекты (например, String) или фактически неизменяемые объекты (например, как построитель на поток) ,
Идея, что StringBuffer должна быть потокобезопасной, всегда была немой идеей, которую показывает IMHO и SimpleDateFormat. –
@PeterLawrey, действительно. Вы абсолютно правы. Я не хотел, однако, добавлять слишком много информации для новичка, у которого есть много нового для изучения. – AlexR
StringBuffer - это домашнее животное, которое меня ненавидит, поэтому я пытаюсь оттолкнуть кого-либо от него;) Еще один использует DataInputStream для текста o_O. –
StringBuffer является только потокобезопасным, если вы вызываете один и только один метод. SimpleDateFormat использует StringBuffer, но не является потокобезопасным (и он был написан разработчиками JVM). Нелегко использовать StringBuffer в потоковом безопасном режиме и правильно его использовать.
Лучше использовать StringBuilder, который был заменен StringBuffer десять лет назад, и использовать явно или Lock
. Это mroe, вероятно, будет фактически потокобезопасным для вашего прецедента.
как использовать явное Синхронное или замок -
Вы размещаете synchronized
блок вокруг операций
например написание новой линии
synchronized(sb) {
sb.append("data: ");
sb.append(data);
sb.append("\n");
}
или захватить содержимое
String s;
synchronized(sb) {
s = sb.toString(); // no simple way to control how many messages you get
sb.setLength(0);
}
как программист может управлять этим.
Скорее всего, вы хотите другой подход. Это связано с тем, что невозможно опросить StringBuilder/StringBuffer и спросить об этом; вы закончили? Если я прочитаю, я могу очистить его простым способом, чтобы буфер можно было повторно использовать. Нет простого способа блокировки, если нет доступных данных. Для писателей также нет параллелизма.
Если вы хотите поделиться поток текста между потоками, я предлагаю использовать
BlockingQueue<String> textStream = new ConcurrentLinkedQueue<>();
Это будет поточно, одновременно поддерживает запись и чтение, и вы можете блокировать в ожидании некоторых данных и знать его это ровно одно сообщение.
Как использовать явный Синхронизированный или блокированный –
@ManishVyas Как и любой другой объект, я обновил свой ответ. Примечание. Это единственный безопасный способ сделать это, даже если вы используете StringBuffer. –
Большое вам спасибо за такое замечательное объяснение. я очень ценю это –
Неизменное означает, что вы не можете изменить объект типа String. Теперь вы должны помнить разницу между фактическими объектами и переменными в вашей программе. Ваши переменные являются простыми ссылками на фактические объекты. Надеюсь, это поможет изменить ваш вопрос. – innoSPG