昨天在社区上看到有人讨论多线程使用,多线程遇到一些问题以及一些使用技巧记录一下。为什么要使用多线程,

不能是为了用而用,和设计模式一样用的合理,会让程序更易于理解,用的不合理反而会让程序变得更难理解。

过去使用场景有,cms内容管理系统多个编辑配置频道,将多个频道以及频道下文章发布成静态html,如果单线程

我们一般是这么去做的,首先通过sql取得全部频道,对频道进行遍历,取到每个频道在取频道下文章列表,然后遍历

文章列表的每一片文章,对每一篇文章标题、作者、简介、内容、图片取出根据配置模版生成html文件,文章列表执

行完一个取下一个频道循环执行。直到所有频道发布完毕,这是整个站点发布完毕,发布过程结束。

上述方式很好完成了发布这个需求,但是作为研发的我们有没有更好、更快方式去搞定这件事情呢?一定有的,

只要我们去想。如果我们将每个频道发布看成一个任务,通过多线程方式并行同时去发布频道那发布时间10个频道

理论上会成为原来10分之一,整个发布减少了时间、提升了性能,用户能够更快看到新内容、新文章。

用多线程要对线程、线程池、同步机制不断学习,因为多线程是好东西,但坑也是很多。稍有不慎就会导致程序bug、

甚至死锁、线上cpu100%服务不可用。

public class MyVisiblility{
private static boolean ready;
private static int number;
private static class MyReaderThread extends Thread{
public void run(){ //读线程
while(!ready)
Thread.yield();
System.out.println(number);
}
public static void main(String [] args){ //主线程
new MyReaderThread().start();
number=42;
ready=true;
}}

这段程序有很大几率输出结果可能为0,也可能是死循环,跟我们期待不一样,原因是什么呢?线程对共享变量

的所有操作都必须在自己的工作内存中进行,不能直接从主线程中获取。因为副本主线程修改子线程为能收到。当

number变量不可见时输出结果为0,当ready不可见时子线程死循环。解决问题方式将变量加上volatile修饰词解决

多线程变量可见性问题。

即程序改为:

public class MyVisiblility{
private static volatile boolean ready;
private static volatile int number;
private static class MyReaderThread extends Thread{
public void run(){ //读线程
while(!ready)
Thread.yield();
System.out.println(number);
}
public static void main(String [] args){ //主线程
new MyReaderThread().start();
number=42;
ready=true;
}}

个性化推荐系统(八)--- 机器学习深度学习召回集扩量这篇文章通过CountDownLatch实现主线程等待

多个计算线程同步,要将CountDownLatch.down()方法用在finally方法中,不要再其他地方,昨天review发现

线上再一个返回逻辑中用了CountDownLatch.down(),再finally中也用了,而finally中时一定会执行的,这时

相当于执行了两次主线程有几率不等待剩余线程向下执行,导致程序偶发bug,这个其实是对finally理解不到位。

再有就是经典HashMap用于多线程而没有用ConcurrentHashMap导致线上服务cpu100%详见这篇记一次双11大促压测线上服务cpu100%

再有就是ThreadLocal变量在ThreadPoolExecuter线程同时使用时,程序异常相见警惕ThreadLocal和ThreadPoolExecutor同时使用

多线程使用好会提升程序性能简化程序实现,使用不好会引入bug、cpu100%、死循环、程序偶发不正确,并且

还不容易定位。这就要求我们要不断研究学习多线程技术,以保证优雅正确将多线程应用到线上服务以及其他各种场景。

java多线程开发容易犯的错误的更多相关文章

  1. Java多线程开发技巧

    很多开发者谈到Java多线程开发,仅仅停留在new Thread(...).start()或直接使用Executor框架这个层面,对于线程的管理和控制却不够深入,通过读<Java并发编程实践&g ...

  2. 十个JAVA程序员容易犯的错误

    十个JAVA程序员容易犯的错误 1. Array 转 ArrayList 一般开发者喜欢用: List<String> list = Arrays.asList(arr); Arrays. ...

  3. Java多线程开发系列之番外篇:事件派发线程---EventDispatchThread

    事件派发线程是java Swing开发中重要的知识点,在安卓app开发中,也是非常重要的一点.今天我们在多线程开发中,穿插进来这个线程.分别从线程的来由.原理和使用方法三个方面来学习事件派发线程. 一 ...

  4. Java多线程开发系列之四:玩转多线程(线程的控制2)

    在上节的线程控制(详情点击这里)中,我们讲解了线程的等待join().守护线程.本节我们将会把剩下的线程控制内容一并讲完,主要内容有线程的睡眠.让步.优先级.挂起和恢复.停止等. 废话不多说,我们直接 ...

  5. Java多线程开发系列之一:走进多线程

    对编程语言的基础知识:分支.选择.循环.面向对象等基本概念理解后,我们需要对java高级编程有一定的学习,这里不可避免的要接触到多线程开发. 由于多线程开发整体的系统比较大,我会写一个系列的文章总结介 ...

  6. java多线程开发,Executors、FutureTask、Callable

    java多线程如何应用呢,几乎学java的同学都知道Thread类和Runable接口.继承Thread类或者实现Runable接口,调用thread的start方法即可启动线程. 然后是线程池,就是 ...

  7. Java多线程开发系列之三:线程这一辈子(线程的生命周期)

    前文中已经提到了,关于多线程的基础知识和多线程的创建.但是如果想要很好的管理多线程,一定要对线程的生命周期有一个整体概念.本节即对线程的一生进行介绍,让大家对线程的各个时段的状态有一定了解. 线程的一 ...

  8. Java多线程开发系列之二:如何创建多线程

    前文已介绍过多线程的基本知识了,比如什么是多线程,什么又是进程,为什么要使用多线程等等. 在了解了软件开发中使用多线程的基本常识后,我们今天来聊聊如何简单的使用多线程. 在Java中创建多线程的方式有 ...

  9. Java多线程开发系列之四:玩转多线程(线程的控制1)

    在前文中我们已经学习了:线程的基本情况.如何创建多线程.线程的生命周期.利用已有知识我们已经可以写出如何利用多线程处理大量任务这样简单的程序.但是当应用场景复杂时,我们还需要从管理控制入手,更好的操纵 ...

随机推荐

  1. java基础解析系列(六)---深入注解原理及使用

    java基础解析系列(六)---注解原理及使用 java基础解析系列(一)---String.StringBuffer.StringBuilder java基础解析系列(二)---Integer ja ...

  2. Linux 安装PHP探针

    学习linux系统还是很有意思的事情,下面这个就是探针,想必有人已经看到过类似的界面主要用来查看自己服务器的运行状况,简单看看内存占用及运行时间就可以了 1 首先要安装Apahce 及 php,命令如 ...

  3. 安装 node-sass 时报错

    在安装 node-sass 时报错,截图如下 解决方法如下: npm install --save node-sass --registry=https://registry.npm.taobao.o ...

  4. bzoj1027 [HNOI2004]打鼹鼠

    [HNOI2004]打鼹鼠 2014年5月2日2,8605 Description 鼹鼠是一种很喜欢挖洞的动物,但每过一定的时间,它还是喜欢把头探出到地面上来透透气的.根据这个特点阿Q编写了一个打鼹鼠 ...

  5. Codeforces Round #410 (Div. 2)C. Mike and gcd problem

    题目连接:http://codeforces.com/contest/798/problem/C C. Mike and gcd problem time limit per test 2 secon ...

  6. 聊聊Java中几种常用的设计模式

    1.单例模式(有的书上说叫单态模式其实都一样) 该模式主要目的是使内存中保持1个对象.看下面的例子: package org.sp.singleton; //方法一 public class Sing ...

  7. centos 7.1系统更改Mariadb数据存储位置步骤分享

    一.首先确保你要更改Mariadb数据存储的位置的空间够大 现在已将Mariadb存储位置更改到/opt/目录下 1.然后将Mariadb服务stop:systemctl stop mariadb 2 ...

  8. ZOJ2402 Lenny's Lucky Lotto List 简单DP

    Lenny's Lucky Lotto Lists Time Limit: 2 Seconds      Memory Limit:65536 KB Lenny likes to play the g ...

  9. [Gitlab运维系列]Gitlab 403 forbidden 并发引起IP被封

    问题 带着团队使用Git,使用的是自搭建的Gitlab.但今天打开页面的时候显示的是空白页面,上面还有一次文本Forbidden. 原因 Gitlab使用rack_attack做了并发访问的限制. 解 ...

  10. Elasticsearch学习笔记 一

    本文版权归博客园和作者吴双本人共同所有 转载和爬虫请注明原文地址 www.cnblogs.com/tdws. 本文参考和学习资料 <ES权威指南> 一.基本概念 存储数据到ES中的行为叫做 ...