Бесплатный курс по Java: от основ до продвинутого уровня
ReadWriteLock в Java
ReadWriteLock – класс содержащий 2 лока: один для чтения, другой для записи.
Часто бывает так, что один поток пишет в ресурс, а много других потоков читают из него.
То есть один поток блокирует ресурс для записи, а другие потоки, желающие читать из ресурса, ждут пока он запишет, и после того, как записывающий закончил запись, потоки читают, и далее всё повторяется.
Пример программы:
import java.io.*;
import java.util.*;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class RedWrtLockExample {
static long numOfOperations=10000000000L;
public static void main(String[] args) {
CommonResource commonResource = new CommonResource(); //объект ресурса
for (int i = 1; i < 4; i++){
//Запускаем 3 потока и передаем в каждый из них
//ресурс общий для потоков.
Thread t =
new Thread(new CountThread(commonResource));
t.setName("Thread " + i);
t.start();
}
//5 раз записать 10 млрд в commonResource.value
for (int i = 0; i < 5; i++) {
//Здесь начинается запись в ресурс потоком мейн
//и пока происходит запись в ресурс потоком мейн
//другие потоки читать из ресурса не смогут.
commonResource.write();
try{
Thread.sleep(100);
}
catch(InterruptedException e){}
}
}
static class CommonResource {
long value;
private final ReadWriteLock lock =
new ReentrantReadWriteLock();
void write() {
//здесь происходит writeLock().lock() на время
//записи десяти млрд блокируем все другие потоки,
//которые дошли до readLock().lock() в этом объекте
lock.writeLock().lock();
for (long i = 0; i < numOfOperations; i++){
value++;
}
//запускаются залоченные в read
lock.writeLock().unlock();
}
void read() {
//Если в каком то из потоков в этом объекте
//случился writeLock().lock() и пока еще не случился
//writeLock().unlock() то readLock().lock()
//останавливает потоки, которые дошли
//до readLock().lock() в этом объекте ресурса.
lock.readLock().lock();
System.out.println("Counter: " + value);
lock.readLock().unlock();
}
}
static class CountThread implements Runnable {
CommonResource res;
CountThread(CommonResource res){
this.res=res;
}
public void run(){
for (int i = 0; i < 5; i++) {
try {
Thread.sleep(200);
}
catch(InterruptedException e){}
//Пока объект заблокирован записью
//чтение потоками не будет происходить.
res.read();
}
}
}
}
Вывод:
Из консоли видно, что три запущенных в мейн потока каждый раз ждут пока мейн запишет 10 миллиардов в переменную value в ресурсе, и каждый раз, как он это сделал потоки выводят переменную value с добавленными 10 миллиардами.
ThreadLocal в Java: создавайте потокобезопасные переменные, уникальные для каждого потока. Пример использования и работа с потоконебезопасными объектами.
Time to read: 16
Fork/Join framework в Java
Fork/Join Framework в Java: разбивайте задачи на подзадачи для параллельного выполнения. Пример использования RecursiveTask и оптимизация многопоточных вычислений.
Time to read: 18
Что такое сериализация в Java
Узнайте, как работает сериализация в Java: сохраняйте объекты в файлы с ObjectOutputStream и восстанавливайте их через ObjectInputStream. Пример кода и важность интерфейса Serializable.