Вот класс Java, который записывает сообщения в параллельном потоке в поток. Когда вызывается метод Stop () , флаг McLoseWriter устанавливается, и поток, который записывает сообщения в потоку, об этом уведомляется. Он также запускает поток с именем MtimeOutThread , который ожидает указанного времени, и если поток, который записывает сообщения, не завершил свое выполнение, оно прерывается. Написание. Будет ли mthread увидеть последнее значение MtimeOutThread ? Потому что MWRITERTHREAD уже завершила свое выполнение (мы назвали mwriterThread.join () из mThread ) и в соответствии с правилами Java все действия в потоке происходят, прежде чем любой другой поток успешно возвращается из join () в этом потоке. />
Если метод Stop () установил флаг Mclosewriter и MwriterThread написал все сообщения и видит из Synchronized (mobject) Block, который McloseWriter устанавливается на TRUE. Здесь Block Synchronized (mobject) также гарантирует, что Mthread увидит значение mtimeOutThread инициализировано методом Stop () . В этом случае исключение будет пойман, и будет вызван метод Tranminate () .
, так как Tranminate () синхронизируется с помощью Synchronized (Mobject) Block, после завершения Tranminate () , MWRITERTHREAD увидит текущее значение mtimeoutThread . И, поскольку Tranminate () также устанавливает значение mexception , которое предотвращает значение mtimeOutThread , которое будет изменено с помощью STOP () , MWRITERTHREAD будет наблюдать за последним возможным значением MTEMOUTTHREAD . Текущее значение mtimeOutThread даже без синхронизированного (mobject) блока, и этот класс не имеет проблем с синхронизацией. Тем не менее, я загрузил этот код в CHATGPT, и он думает, что есть раса данных. Итак, код ниже синхронизирован ли ниже? < /P>
public class MessageWriter {
private final OutputStream mStream;
private Thread mWriterThread;
private Thread mTimeoutThread;
private boolean mCloseWriter;
private Thread mThread;
private final Object mObject = new Object();
private Exception mException;
private final Listener mListener;
private final LinkedList mMessageQueue = new LinkedList();
public MessageWriter(OutputStream stream, Listener listener) {
mStream = stream;
mListener = listener;
start();
}
private void start() {
synchronized (mObject) {
mThread = new Thread(() -> {
startWriterThread();
joinThread(mWriterThread);
/*Is it safe to access mTimeoutThread without
a synchronized block here?*/
if (mTimeoutThread != null) {
joinThread(mTimeoutThread);
}
mListener.onClosed(mException);
});
mThread.start();
}
}
private void startWriterThread() {
synchronized (mObject) {
mWriterThread = new Thread(() -> {
try {
loopWriter();
} catch (Exception e) {
terminate(e);
}
});
mWriterThread.start();
}
}
public void stop() {
synchronized (mObject) {
if (!mCloseWriter && mException == null) {
mCloseWriter = true;
mTimeoutThread = new Thread(() -> {
try {
waitAndThrow(5000);
} catch(InterruptedException ignored){
} catch (Exception e) {
terminate(e);
}
});
mTimeoutThread.start();
mObject.notifyAll();
}
}
}
private void terminate(Exception exception) {
synchronized (mObject) {
if (mException == null) {
mException = exception;
mWriterThread.interrupt();
mTimeoutThread.interrupt();
mThread.interrupt();
}
}
}
private static void joinThread(Thread thread) {
do {
try { thread.join(); } catch (InterruptedException ignored) {}
} while (thread.isAlive());
}
private byte[] nextMessage() throws InterruptedException {
synchronized (mObject) {
while (mMessageQueue.isEmpty()) {
if (mCloseWriter) return null;
mObject.wait();
}
return mMessageQueue.remove();
}
}
private void loopWriter() throws InterruptedException, IOException {
while (true) {
final byte[] message = nextMessage();
if (message == null) {
synchronized (mObject) {
mTimeoutThread.interrupt();
}
return;
}
mStream.write(message);
}
}
public void writeMessage(byte[] message) {
synchronized (mObject) {
if (mCloseWriter || mException != null) {
return;
}
if (mMessageQueue.isEmpty()) {
mObject.notifyAll();
}
mMessageQueue.add(message);
}
}
private static void waitAndThrow(long timeoutMillis) throws InterruptedException {
for (long deadline = System.currentTimeMillis() + timeoutMillis;;) {
final long currentUptime = System.currentTimeMillis();
if (currentUptime
Подробнее здесь: https://stackoverflow.com/questions/797 ... -memory-vi