Answer the question
In order to leave comments, you need to log in
How to put a thread to sleep before a signal from another thread?
There are 2 streams. They take one Runnable from the common array and execute it and remove it from the array. From other flows these same Runnable are interposed. But when using wait and notify or ReentrantLock.Condition await/signal I have IllegalMonitorStateException
package ru.irina.mongo;
import com.mongodb.DB;
import com.mongodb.MongoClient;
import com.mongodb.MongoCredential;
import com.mongodb.ServerAddress;
import java.util.ArrayList;
import java.util.Collections;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
public class MongoWorkers {
private final static ArrayList<Runnable> tasks = new ArrayList<>();
private final static ArrayList<DB> mongoDatabases = new ArrayList<>();
private final static ArrayList<Worker> workers = new ArrayList<>();
private static final Condition condition = new ReentrantLock().newCondition();
public static void putTask(Runnable task) {
synchronized (tasks) {
tasks.add(task);
}
condition.signalAll();
}
public static void runWorkers(int threadCount) {
if (!mongoDatabases.isEmpty())
throw new IllegalStateException("Workers уже started");
for (int i = 0; i < threadCount; ++i) {
Worker worker = new Worker();
worker.start();
workers.add(worker);
}
System.out.println("[Worker] started " + threadCount + " threads");
}
public static DB getDB() {
System.out.println("[Worker] request DB");
synchronized (mongoDatabases) {
if (!mongoDatabases.isEmpty()) {
DB db = mongoDatabases.get(0);
mongoDatabases.remove(0);
return db;
}
return null;
}
}
public static void returnDB(DB db) {
System.out.println("[Worker] return DB");
synchronized (mongoDatabases) {
mongoDatabases.add(db);
}
}
static class Worker extends Thread {
Worker() {
synchronized (mongoDatabases) {
mongoDatabases.add(db);
}
setDaemon(true);
}
@Override
public void run() {
while (isAlive()) {
Runnable runnable = null;
synchronized (tasks) {
if (!tasks.isEmpty()) {
runnable = tasks.get(0);
tasks.remove(0);
}
}
if (runnable != null)
runnable.run();
else {
try {
condition.await();
} catch (InterruptedException e) {
// ...
}
}
}
}
}
}
Answer the question
In order to leave comments, you need to log in
await
and notify
can only be called on the captured monitor.
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question