我们如何在执行者框架中模拟饥饿?

时间:2018-04-13 05:07:18

标签: java multithreading concurrency java.util.concurrent

我想模拟我们在生产环境中遇到的挂起线程。该应用程序是一个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();
    }
}

2 个答案:

答案 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();
    }
}