我想模拟我们在生产环境中遇到的挂起线程。该应用程序是一个Web服务,为新请求创建了不同的线程。错误是所有线程都依赖于同步方法,并且已在补丁中删除了依赖项。 任何指针如何在开发环境中模拟执行程序框架的挂起线程?
在开发中,一切都很好,我怎样才能确保某些线程挂起用于同步方法,就像生产一样?
package com.priority;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class StackOverFlow {
public static void main(String[] args) {
ExecutorService executorService = Executors.newFixedThreadPool(10);
for (int i = 0; i < 100; i++) {
executorService.submit(new Task());
}
executorService.shutdown();
}
}
class Task implements Runnable {
synchronized void syncMethod() {
System.out.println("This is the sync method causing issues");
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@Override
public void run() {
syncMethod();
}
}
答案 0 :(得分:0)
假设同步资源(synchronized void syncMethod())在某个其他类中,以便执行程序服务之外的线程可以访问它。需要重构才能重新创建饥饿场景。
创建一些贪婪线程,这些线程会随机保留同步资源(超过普通线程)。此类线程的数量可能取决于您的测试场景。
在执行者服务之前触发贪婪线程,以便他们获取资源。
现在,您可以测试真实线程在资源稀缺情况下的响应方式,并定义在不平衡使用情况下管理资源的策略。
答案 1 :(得分:0)
如果没有显式对象,synchronized
将在this
上执行,因此您发布的代码不会同步。
您应该为这些任务提供相同的监视器锁定:
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class StackOverFlow {
public static void main(String[] args) {
Object monitor = new Object();
ExecutorService executorService = Executors.newFixedThreadPool(10);
for (int i = 0; i < 100; i++) {
executorService.submit(new Task(monitor));
}
executorService.shutdown();
}
}
class Task implements Runnable {
Object monitor;
public Task(Object monitor) {
this.monitor = monitor;
}
void syncMethod() {
synchronized (monitor) {
System.out.println("This is the sync method causing issues");
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
@Override
public void run() {
syncMethod();
}
}