无锁编程的一点想法

在多线程环境下,对共享资源的修改,是一定要加锁的。
但是在高并发的环境下,锁竞争的代价非常高.

一些针对共享资源的修改,过程非常短暂,可以考虑使用串行化,适当限制并发
同时也避免了死锁的风险.

实验模拟了一个场景
一个Servlet要统计访问的总数,并且访问数据库获取数据.

常规的方式如下


针对共享资源的修改,可以使用串行的方式,之后访问数据库等操作,还是以多线程的方式运行。


样例代码如下:

  1. import java.io.IOException;
  2. import java.util.concurrent.Callable;
  3. import java.util.concurrent.ExecutionException;
  4. import java.util.concurrent.Executors;
  5. import java.util.concurrent.Future;
  6. import java.util.concurrent.FutureTask;
  7. import java.util.concurrent.LinkedBlockingQueue;

  8. import javax.servlet.ServletException;
  9. import javax.servlet.annotation.WebServlet;
  10. import javax.servlet.http.HttpServlet;
  11. import javax.servlet.http.HttpServletRequest;
  12. import javax.servlet.http.HttpServletResponse;

  13. /**
  14.  * Servlet implementation class CharsetTest
  15.  */
  16. @WebServlet("/CharsetTest")
  17. public class CharsetTest extends HttpServlet {

  18.     int count = 0;
  19.     private LinkedBlockingQueue<FutureTask<Integer>> q = new LinkedBlockingQueue<FutureTask<Integer>>();

  20.     {
  21.         Executors.newSingleThreadExecutor().submit(new Runnable() {

  22.             @Override
  23.             public void run() {
  24.                 FutureTask futureTask;
  25.                 try {
  26.                     while ((futureTask = q.take()) != null) {
  27.                         futureTask.run();
  28.                     }
  29.                 } catch (InterruptedException e) {
  30.                     e.printStackTrace();
  31.                 }

  32.             }

  33.         });
  34.     }

  35.     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  36.         int current = -1;
  37.         Callable<Integer> c = new Callable<Integer>() {
  38.             @Override
  39.             public Integer call() throws Exception {
  40.                 count++;
  41.                 return count;
  42.             }
  43.         };
  44.         FutureTask<Integer> f = new FutureTask<Integer>(c);
  45.         try {
  46.             q.put(f);
  47.             current = f.get();
  48.         } catch (InterruptedException e) {
  49.             e.printStackTrace();
  50.         } catch (ExecutionException e) {
  51.             e.printStackTrace();
  52.         }
  53.         dbSelect();
  54.         System.out.println(current);
  55.     }

  56.     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException,
  57.             IOException {
  58.         doGet(request, response);
  59.     }

  60.     private void dbSelect() {
  61.     }

  62. }

请使用浏览器的分享功能分享到微信等