
Версия 2.2:
package lab_3;
import java.util.concurrent.locks.*;
public class SynchronizedString {
private String data;
private boolean isWriting;
private int numActiveReaders;
private Lock lock;
private Condition canWrite; //Условие ожидания для операции записи
private Condition canRead; //Условие ожидания для операции чтения
public SynchronizedString() {
data = "";
isWriting = false;
numActiveReaders = 0;
lock = new ReentrantLock();
canWrite = lock.newCondition();
canRead = lock.newCondition();
}
public void write(String newData) throws InterruptedException {
lock.lock(); //Блокировка для эксклюзивного доступа к данным
try {
while (isWriting) {
canWrite.await(); //Ожидает, пока другой поток не закончит операцию записи
}
isWriting = true; //Флаг, что выполняется запись
//while (numActiveReaders > 0) {
// canRead.await(); //Ожидает, пока активные потоки-читатели не завершат операции чтения
//}
data = newData;
isWriting = false; //Операция записи завершена
canWrite.signal(); //Сигнализирует ожидающему потоку, что операция записи завершена и другой поток может начать запись
} finally {
lock.unlock(); //Освобождение блокировки после завершения
}
}
public String read() throws InterruptedException {
lock.lock(); //Блокировка для эксклюзивного доступа к данным
try {
while (isWriting) {
canRead.await(); //Ожидает, пока другой поток не закончит операцию записи
}
//numActiveReaders++; //Увеличение счетчика активных потоков-читателей
String result = data;
//numActiveReaders--;
//System.out.println("numActiveReaders" + numActiveReaders);
//if (numActiveReaders == 0) {
// canWrite.signal(); //Если нет активных потоков-читателей, сигнализирует ожидающему потоку записи, что можно начать операцию записи
//}
return result;
} finally {
lock.unlock();
}
}
}
-----
public static void main(String[] args) {
SynchronizedString synchronizedString = new SynchronizedString();
int numWriters = 10;
int numReaders = 5;
Thread[] writerThreads = new Thread[numWriters]; // Массив потоков писателей
Thread[] readerThreads = new Thread[numReaders]; // Массив потоков читателей
// Создание и запуск потоков-писателей
for (int i = 0; i < numWriters; i++) {
final int writerNumber = i + 1;
Thread writerThread = new Thread(() -> {
try {
synchronized (synchronizedString) {
String input = "ЗДЕСЬ ПОТОК НОМЕР " + Integer.toString(writerNumber) + "!";
synchronizedString.write(input);
System.out.println("Writer Thread " + writerNumber + ": Успешно записал '" + input + "'");
}
} catch (InterruptedException e) {
e.printStackTrace();
}
});
writerThreads[i] = writerThread; // Сохранение ссылки на поток в массиве
writerThread.start();
}
// Создание и запуск потоков-читателей
for (int i = 0; i < numReaders; i++) {
final int readerNumber = i + 1;
Thread readerThread = new Thread(() -> {
try {
synchronized (synchronizedString) {
String value = synchronizedString.read();
System.out.println("Reader Thread " + readerNumber + ": Прочитано значение: " + value);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
});
readerThreads[i] = readerThread; // Сохранение ссылки на поток в массиве
readerThread.start();
}
try {
for (int i = 0; i < numWriters; i++) {
writerThreads[i].join();
}
for (int i = 0; i < numReaders; i++) {
readerThreads[i].join();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Все потоки завершили работу");
}