zoukankan      html  css  js  c++  java
  • java 多线程并发问题

    问题:50个线程,先查询数据库的一个记录 t,然后对这个记录+1,最后更新到数据库

    更新的时候,不允许使用 update  test_concurrent set sum =sum -1 where id=1,如果这个做就看不出来效果了,必须使用update  test_concurrent set sum =? where id=1)。

    1.创建表

    CREATE TABLE `test_concurrent` (
    `id` bigint(20) NOT NULL AUTO_INCREMENT,
    `sum` bigint(20) DEFAULT NULL COMMENT '并发的和',
    PRIMARY KEY (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;

    2.表里只有一条记录

    INSERT INTO `test_concurrent` VALUES (1, 0);

    对于这种并发问题有三种解决方法

    1.使用悲观锁  select for update

    2.使用乐观锁 新增一个字段,查询时设置这个字段,更新时根据这个字段更新

    3.update  test_concurrent set sum =? where id=1 and sum =#{t}

    4.update  test_concurrent set sum =sum-? where id=1 and sum >=?   

    总和来说:4是最好的写法。

    并发线程代码

    @Test
        public void testAdd1() {
            log.info("开始执行----------------");
            CountDownLatch latch = new CountDownLatch(50);
            
            ExecutorService executor=new ThreadPoolExecutor(10, 50, 2000, TimeUnit.SECONDS, new ArrayBlockingQueue(50));
            AtomicInteger integer=new AtomicInteger(0);
            for(int i=0;i<50;i++){
                Integer s=i;
                executor.execute(new Runnable() {
                    @Override
                    public void run() {
                        //log.info("开始执行----------------{}",s);
                        service.add1(1);
                        log.info("开始执行----------------{}",s);
                        integer.incrementAndGet();
                        latch.countDown();
                    }
                });
                
                
            }
            try {
                latch.await();
            } catch (InterruptedException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
            log.info("开始执行----------------{}",integer.intValue());

     注意:线程池的用法

  • 相关阅读:
    移动端web app开发备忘
    HDU 5391-Zball in Tina Town(数论)
    LeetCode:Invert Binary Tree
    Mongo集群之主从复制
    Cocos2d-x--iOS平台lua加密成luac资源方法和Jsc文件&lt;MAC平台开发试用--windows平台暂未研究&gt;
    优秀程序猿因何而优秀?
    Java Exception和Error的差别
    【Android开发】之Fragment与Acitvity通信
    Draw the RGB data from kinect C++ via opengl
    使用Opencv2遇到error C2061: 语法错误: 标识符dest
  • 原文地址:https://www.cnblogs.com/z-test/p/10256467.html
Copyright © 2011-2022 走看看