前端时间一个同事因为后台线程安全问题出了一次生产事故,今天我就对线程安全问题进行一次总结。  

  首先,我们来大致看以下我同事写的代码,代码我进行了精简,大致如下:

 for (final String receiver : getReceivers())
{
sendThreadPool.excute(new Runnable() {
public void run()
{
newMessage.setTo(receiver);
MessageProductor.sendMessage(newMessage);
}
});
}

  不知道大家有没有发现什么问题,这个方法的作用时将一条消息发送给N个人,但是得到的结果却是部分人没有收到,部分人收到了两次。

  相信大家也从上面的代码中发现问题了,原因是newMessae同时被多个线程修改和访问,最终导致该实体被其他线程修改。

  基于此问题,我对这种多线程的建议如下:

    1、线程内尽量不访问线程外的对象

       对于上面的示例,建议在线程外将newMessage序列化,再作为线程参数传入线程,再在线程内反序列化。

    2、如果线程内需要访问线程外的对象,建议采用线程安全类型或者加锁

          对于上面的示例,可改为如下代码

        private static Lock lock = new ReentrantLock();
for (final String receiver : getReceivers())
{
sendThreadPool.excute(new Runnable() {
public void run()
{
lock.lock () ;
newMessage.setTo(receiver);
MessageProductor.sendMessage(newMessage);
lock.unlock();
}
});
}

      

  下面我来对Java中实现线程安全的方式进行下总结:

  加锁

  常用的锁有如下三种:

(1)synchronized 是互斥锁;

(2)ReentrantLock 顾名思义 :可重入锁

(3)ReadWriteLock :读写锁

  原子类型

  常用的原子类型如下:

(1)AtomicInteger和AtomicIntegerArray:基于Integer类型

(2)AtomicBoolean:基于Boolean类型

(3)AtomicLong和AtomicLongArray:基于Long类型

(4)AtomicReference和AtomicReferenceArray:基于引用类型

  线程安全类

(1)Vector

(2)HashTable

(3)StringBuffer

  以上几点看起来很简单,特别是StringBuffer,很多Java岗位的面试都会问道StringBuffer和StringBuilder的区别,需要大家一定记住,StringBuilder是线程安全的类。

Java后台技术(线程安全)的更多相关文章

  1. Java后台技术(TDDL)

    从PC客户端开发转项目经理已经有一段时间了,感觉还不错,平安这边的项目经理还需要对外,所以部门其他项目经理经常需要出差去见客户,我专门对内,部门所有的开发和测试每天做什么.接下来做什么我都必须了解,部 ...

  2. Java后台技术(Dubbo入门)

    我现在公司提供的产品是即时通讯软件,因为我从.net桌面应用开发转岗,从java后台转项目经理,让我有幸拥有了后台开发人员所有的权限,所有的后台源码和技术文档对我开放,可惜仅在后台待了3周不到,还没来 ...

  3. java后台技术

    本文旨在梳理服务端开发技术栈,希望帮助后端开发同学更全面了解Java服务端主要涉及的知识点 1. 语言相关 1.1 Java 核心知识点 Java的类加载机制 JVM相关:JVM内存模型和结构,GC原 ...

  4. Java后台技术IBATIS入门

    做过.net后台开发的同志一定用过Entity FrameWork,该框架实现了实体Entity到数据库行的映射,通过操作实体DataSet,就能够直接同步修改到数据库.但是Java暂时没有类似的技术 ...

  5. Java 后台线程介绍

    一  是啥? package com.aaa.threaddemo; /* * 一 Java后台线程? * 守护线程--也称"服务线程",他是后台线程, * 它有一个特性,即为用户 ...

  6. Java多线程与线程池技术

    一.序言 Java多线程编程线程池被广泛使用,甚至成为了标配. 线程池本质是池化技术的应用,和连接池类似,创建连接与关闭连接属于耗时操作,创建线程与销毁线程也属于重操作,为了提高效率,先提前创建好一批 ...

  7. Java多线程技术学习笔记(二)

    目录: 线程间的通信示例 等待唤醒机制 等待唤醒机制的优化 线程间通信经典问题:多生产者多消费者问题 多生产多消费问题的解决 JDK1.5之后的新加锁方式 多生产多消费问题的新解决办法 sleep和w ...

  8. java后台常见问题

    Java后台面试 常见问题 Nginx负载均衡 轮询.轮询是默认的,每一个请求按顺序逐一分配到不同的后端服务器,如果后端服务器down掉了,则能自动剔除 ip_hash.个请求按访问IP的hash结果 ...

  9. 一年工作经验的大专生程序员(java后台)

    1.文章前言     作为18应届毕业大专生已工作一年,相信这也是大部分同届生的现状.       那么,一个萌新进入职场一年都经历了什么呢?在校那会我是挺好奇的.       这篇文章是根据自己一年 ...

随机推荐

  1. Tomcat创建项目

    查看项目信息 index.jsp默认首页 更新资源自动部署不用重启服务器,要用debug的方式启动 更新java代码和更新资源自动部署不用重启服务器,要用debug的方式启动

  2. MVC5+EF6 入门完整教程4 :EF基本的CRUD

    上篇文章主要讲了如何配置EF, 我们回顾下主要过程: 创建Data Model ---> 创建Database Context --->创建databaseInitializer---&g ...

  3. 题解【洛谷P1841】[JSOI2007]重要的城市

    题面 题解 最短路图模板题. 介绍一下最短路图: 先对原图跑一边单源最短路,求出源点到每个点\(i\)的最短路\(dis[i]\). 接下来构建新图:对于一条边\((x,y,v)\),若\(dis[x ...

  4. 转载:EQ--biquad filter

    http://www.musicdsp.org/files/Audio-EQ-Cookbook.txt https://arachnoid.com/BiQuadDesigner/index.html ...

  5. Linux上后台运行node和springboot服务

    环境:Ubuntu18.04 阿里云云服务器 尝试全局安装forever和pm2均失败,最后以linux自带的nohub启动,以前同样用nohub启动springboot 命令: nohup npm ...

  6. angular清空node_modules

    安装全局包 npm install rimraf -g 执行清空命令 rimraf node_modules

  7. gVim for windows 简单使用教程

    vim 是一个具有很多命令的功能非常强大的编辑器.限于篇幅,在本教程当中    就不详细介绍了.本教程的设计目标是讲述一些必要的基本命令,而掌握好这    些命令,您就能够很容易将vim当作一个通用的 ...

  8. 第二十九篇 玩转数据结构——线段树(Segment Tree)

          1.. 线段树引入 线段树也称为区间树 为什么要使用线段树:对于某些问题,我们只关心区间(线段) 经典的线段树问题:区间染色,有一面长度为n的墙,每次选择一段墙进行染色(染色允许覆盖),问 ...

  9. Bugku-CTF分析篇-抓到一只苍蝇(在哪?here!卧槽?!好大一坨苍蝇。)

    抓到一只苍蝇 抓到一只苍蝇         本题要点:pcapng包导出文件.合并连续的pcapng包.rar文件头.binwalk基本使用.foremost安装及使用     下载完成后,发现有这样 ...

  10. ubuntu12.04安装Opencv2.4.9

    之前在Linux下装过几次opencv,但几乎每次都要查一下怎么安装,这次索性记录一下安装过程,不用每次都看其他人的教程了. 至于安装过程,可以直接参考官方文档.在解压后的文件夹下opencv\bui ...