说明
这是针对《Java并发编程实战》(Java Concurrency in Practice)一书中的示例代码进行扩展,并且进行验证的完整代码,具体背景可看这篇文章:1-《Java并发编程实战》(Java Concurrency in Practice) 代码示例
下面的示例代码都是针对书中的(不完整的)代码扩展,不再介绍具体上下文背景(如果你也在看这本书,可以拿我这里的示例代码做个参考,并欢迎提出意见和建议)
程序清单2-5
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;/*** @DESCRIPTION:* @USER: shg* @DATE: 2024/1/13 11:15*/
public class UnsafeCachingFactorizer extends HttpServlet {private final AtomicReference<BigInteger> lastNumber = new AtomicReference<>();private final AtomicReference<BigInteger[]> lastFactors = new AtomicReference<>();@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {BigInteger i = extractFromRequest(req);if (i.equals(lastNumber.get())) {encodeIntoResponse(resp, i, lastFactors.get());} else {BigInteger[] factors = factor(i);lastNumber.set(i);lastFactors.set(factors);encodeIntoResponse(resp, i, lastFactors.get());}}private BigInteger extractFromRequest(HttpServletRequest req) {return new BigInteger(req.getParameter("key"));}private void encodeIntoResponse(HttpServletResponse resp, BigInteger i, BigInteger[] factors) throws IOException {System.out.println(i + "--->" + Arrays.asList(factors));resp.setContentType("text/html;charset=utf-8");PrintWriter writer = resp.getWriter();writer.println("<html><body>");writer.println("<h1>" + i + "因数分解结果为:" + Arrays.asList(factors));writer.println("</body></html>");}private BigInteger[] factor(BigInteger number) {List<BigInteger> factors = new ArrayList<>();BigInteger divisor = BigInteger.valueOf(2);while (number.compareTo(BigInteger.ONE) > 0) {if (number.mod(divisor).equals(BigInteger.ZERO)) {number = number.divide(divisor);factors.add(divisor);} else {divisor = divisor.add(BigInteger.ONE);}}return factors.toArray(new BigInteger[0]);}
}
压测线程设置
使用Jmeter开启两个线程组,每个线程组传递的参数不一样,但是访问同一个Servlet组件(即:访问同一个UnsafeCachingFactorizer类),然后在控制台分析输出结果,具体操作如下图:
压测结果分析
首先要明确的是,这是一个Servlet组件(即:UnsafeCachingFactorizer类)的功能是因数分解,并且希望将最近的计算结果缓存起来,即当两个连续的请求对相同的数值进行因数分解时,可以直接使用上一次的计算结果,而无需重新计算。
并且我们可以事先知道是的129的因数分解结果应该是 3和43;24的因数分解结果应该是:2,2,2和3,现在看如下图: