gpt4 book ai didi

Java多线程,Thread.sleep暂停当前线程但不会继续其他线程

转载 作者:行者123 更新时间:2023-11-29 07:23:29 25 4
gpt4 key购买 nike

我正在练习使用 Java 的对象池设计模式。并创建了示例并尝试运行我的代码。

程序在池中提供有限数量的对象和异步进程的运行数量。

我的代码只是简单地从池中取出一个对象(如果没有可用的对象并且对象的数量小于限制则创建新对象)并在 Thread.sleep 之后返回。但不知何故,其他线程一直在循环,找不到任何可用的对象。

public abstract class ObjectPool<T> {

private long waitingTime;
private int maxObjectPoolSize;

private final List<T> available = Collections.synchronizedList(new ArrayList<>());
private final List<T> inUse = Collections.synchronizedList(new ArrayList<>());

protected AtomicInteger count = new AtomicInteger(0);
private AtomicBoolean waiting = new AtomicBoolean(false);

public abstract T create();

public ObjectPool(int poolSize) {
waitingTime = 1200;
setMaxObjectPoolSize(poolSize);
}

public void setMaxObjectPoolSize(int poolSize) {
this.maxObjectPoolSize = poolSize;
}

public synchronized T getObject() {
if (!available.isEmpty()) {
T o = available.remove(0);
inUse.add(o);
return o;
}
// if max pool size, wait for object to be released
if(count.get() == maxObjectPoolSize) {
this.waitUntilNextAvailable();
return this.getObject();
}
// if no objects available, create new one
T o = this.create();
this.inUse.add(o);
return o;
}

public synchronized void releaseObject(T o) {
this.inUse.remove(o);
this.available.add(o);
System.out.println(o.toString() + " is free");
}

private void waitUntilNextAvailable() {
// if (waiting.get()) {
// waiting.set(false);
// throw new ObjectNotFoundException("No Object Available");
// }
// waiting.set(true);
System.out.println(Thread.currentThread().getName());
waiting(waitingTime);
}

public void waiting(long ms) {
try {
TimeUnit.MILLISECONDS.sleep(ms);
} catch (InterruptedException e) {
e.printStackTrace();
Thread.currentThread().interrupt();
}
}
}
public class ProcessThread implements Runnable {

private RoomPool pool;

public ProcessThread(RoomPool pool) {
this.pool = pool;
}

@Override
public void run() {
takeAnObject();
}

private void takeAnObject() {
try {
System.out.println("New process: " + Thread.currentThread().getName());
Room room = pool.getObject();

TimeUnit.MILLISECONDS.sleep(randInt(1000, 1500));

pool.releaseObject(room);
System.out.println("executed: " + Thread.currentThread().getName());
} catch (InterruptedException | ObjectNotFoundException e) {
System.out.println(">>>> Process Rejected: " + Thread.currentThread().getName());
}
}

private static int randInt(int min, int max) {
return new Random().nextInt((max - min) + 1) + min;
}
}
public class Main {

public static final int OBJECT_POOL_SIZE = 4;

public static final int NUMBER_OF_PROCESSES = 10;

public static void main(String[] args) {
RoomPool pool = new RoomPool(OBJECT_POOL_SIZE);
for (int i = 1; i <= NUMBER_OF_PROCESSES; i++) {
Runnable process = new ProcessThread(pool);
Thread thread = new Thread(process);
thread.start();
}
}
}

New process: Thread-5
New process: Thread-8
New process: Thread-3
New process: Thread-0
New process: Thread-4
New process: Thread-6
New process: Thread-7
New process: Thread-2
New process: Thread-1
New process: Thread-9
Room name = Room 1 is created
Room name = Room 2 is created
Room name = Room 3 is created
Room name = Room 4 is created
Thread-7
Thread-7
Thread-7
Thread-7
Thread-7
Thread-7

我不明白为什么线程不返回池中的对象。

我尝试在我的 IDE 上调试它,我看到线程处于 SLEEP 状态后,它会进入 MONITOR。我是这个多线程事物的新手,所以我不知道这是否正常。

任何帮助将不胜感激

最佳答案

您已使 ObjectPool 的方法同步。

意味着没有线程可以“释放”一个对象(synchronized releaseObject(To) 如果有任何线程已经“获取”一个对象 synchronized getObject()

与其让整个方法同步,不如想办法只修改 inUse/available 的原子性。

尝试从“getObject”中删除同步,而是只同步列表中的第一个添加/删除,如下所示:

public T getObject() {
if (!available.isEmpty()) {
synchronized(this) {
T o = available.remove(0);
inUse.add(o);
}
return o;
}
....

关于Java多线程,Thread.sleep暂停当前线程但不会继续其他线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59310914/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com