美文网首页大前端开发
Android 多线程优化那些事

Android 多线程优化那些事

作者: dear_qi | 来源:发表于2019-05-12 17:43 被阅读133次

    背景

    年初开发了一个项目,项目中有这样一个需求,需要每隔一秒钟向服务器发起一次状态信息查询指令,在这个过程中偶尔会主动发起一次状态信息修改的指令(PS:因为服务器的处理能力有限,必须间隔一秒才能发送命令,否则指令将不会被执行)。本来不是什么大问题,但是由于开发人员从事android开发时间较短,多线程用得也不多,所以看似简单的问题,最后使得整个项目出现了较大的性能问题。下面主要讲讲如何一步步的优化过程。(本文适合初学者,大牛可以绕道前行)。

    优化前

    以下是功能部分代码

        public void sendOrderToServer(final byte[] data) {
            Thread thread = new Thread(new Runnable()
            {
                @Override
                public void run()
                {
                    order_queue.offer(data);//将指令放入队列中
                    if (null != order_queue && order_queue.size() != 0) {
                        synchronized (lock) {
                            while (order_queue.size() != 0) {
                                try {
                                      byte[] orderData = order_queue.poll();//取出队首指令
                                      int dataLength = orderData.length; 
                                      if (dataLength > 0) {
                                          //发送指令到服务器
                                      }
                                      try {
                                          Thread.sleep(1000);//等待一秒钟,然后执行下一条指令
                                      } catch (InterruptedException e) {
                                          e.printStackTrace();
                                      }
                                  } catch (IOException e) {
                                      e.printStackTrace();
                                  }
                              }
                          }
                      }
                 }
              });
              thread.start();
         }
    

    代码很简单,相信大家都能看懂是什么意思,阅读下来好像也没什么太大问题。模拟器运行一遍,没有问题,各项数据显示正常。然后信心满满安装到真机上,拍拍手,欧✌️,搞定。可惜理想是美好的,现实是残酷的,分分钟啪啪啪打脸。app运行不到一分钟,整个界面就开始卡顿了,操作屏幕毫无反应。这是为啥呢 ???

    然后认真阅读了一下代码,发现里面用到了synchronized (lock)同步锁,笔者为什么要这样写,估计是考虑到指令需要间隔一秒钟才能发送,又要保证指令是按序的。由于app每次发送命令都需要调用sendOrderToServer方法,并创建新的线程。这就出现了一个问题,除了第一个线程能获取到同步锁,其他的线程都无法获取到,因为order_queue队列永远不会为空。那么其他线程都相当于死锁,都无法执行后面的代码,也就不能释放占用的系统资源。这样线程不停的创建,系统资源被一点点消耗掉,最后造成界面卡顿。既然问题找到了,那就好办了,其实优化方法有很多,下面只是其中一种。

    优化后

    public void sendOrderToServer(final byte[] data) {
             order_queue.offer(data);
    }
    
    private class WriteThread extends Thread {
            @Override
            public void run() {
                super.run();
                while (true) {
                    if (null != order_queue && order_queue.size() != 0) {
                            byte[] orderData = order_queue.poll();
                            if (null != orderData) {
                                int dataLength = orderData.length;
                                if (dataLength > 0) {
                                    //发送指令到服务器
                                }
                            }
                            try {
                                Thread.sleep(1000);
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }
    

    只创建一个WriteThread对象,里面运行一个while (true)的循环,发送指令时只需要调用sendOrderToServer方法,往order_queue队列中加入指令就好。

    总结

    1、项目中使用多线程加锁时,需要注意不要造成死锁。
    2、如果需要创建大量的线程,请使用线程池来管理,减少线程创建的开销,以及资源的浪费。

    相关文章

      网友评论

        本文标题:Android 多线程优化那些事

        本文链接:https://www.haomeiwen.com/subject/dyafoqtx.html