本文来自:高爽|Coder,原文地址:http://blog.csdn.net/ghsau/article/details/7421217,转载请注明。

当我们查看JDK API的时候,总会发现一些类说明写着,线程安全或者线程不安全,比如说StringBuilder中,有这么一句,“将StringBuilder 的实例用于多个线程是不安全的。如果需要这样的同步,则建议使用StringBuffer。 ”,那么下面手动创建一个线程不安全的类,然后在多线程中使用这个类,看看有什么效果。

 public class Count {
private int num;
public void count() {
for(int i = 1; i <= 10; i++) {
num += i;
}
System.out.println(Thread.currentThread().getName() + "-" + num);
}
}

在这个类中的count方法是计算1一直加到10的和,并输出当前线程名和总和,我们期望的是每个线程都会输出55。

ThreadTest.java:

 public class ThreadTest {
public static void main(String[] args) {
Runnable runnable = new Runnable() {
Count count = new Count();
public void run() {
count.count();
}
};
for(int i = 0; i < 10; i++) {
new Thread(runnable).start();
}
}
}

这里启动了10个线程,看一下输出结果:

 Thread-0-55
Thread-1-110
Thread-2-165
Thread-4-220
Thread-5-275
Thread-6-330
Thread-3-385
Thread-7-440
Thread-8-495
Thread-9-550 

只有Thread-0线程输出的结果是我们期望的,而输出的是每次都累加的,这里累加的原因以后的博文会说明,那么要想得到我们期望的结果,有几种解决方案:

1. 将Count中num变成count方法的局部变量;

 public class Count {
public void count() {
int num = 0;
for(int i = 1; i <= 10; i++) {
num += i;
}
System.out.println(Thread.currentThread().getName() + "-" + num);
}
}

2. 将线程类成员变量拿到run方法中,这时count引用是线程内的局部变量;

上述测试,我们发现,存在成员变量的类用于多线程时是不安全的,不安全体现在这个成员变量可能发生非原子性的操作,而变量定义在方法内也就是局部变量是线程安全的。想想在使用struts1时,不推荐创建成员变量,因为action是单例的,如果创建了成员变量,就会存在线程不安全的隐患,而struts2是每一次请求都会创建一个action,就不用考虑线程安全的问题。所以,日常开发中,通常需要考虑成员变量或者说全局变量在多线程环境下,是否会引发一些问题。

java线程系列文章之一(线程的安全性)的更多相关文章

  1. java nio系列文章

    java nio系列教程 基于NIO的Client/Server程序实践 (推荐) java nio与并发编程相关电子书籍   (访问密码 48dd) 理解NIO nio学习记录 图解ByteBuff ...

  2. 线程系列08,实现线程锁的各种方式,使用lock,Montor,Mutex,Semaphore以及线程死锁

    当涉及到多线程共享数据,需要数据同步的时候,就可以考虑使用线程锁了.本篇体验线程锁的各种用法以及线程死锁.主要包括: ※ 使用lock处理数据同步※ 使用Monitor.Enter和Monitor.E ...

  3. 死磕 java线程系列之创建线程的8种方式

    (手机横屏看源码更方便) 问题 (1)创建线程有哪几种方式? (2)它们分别有什么运用场景? 简介 创建线程,是多线程编程中最基本的操作,彤哥总结了一下,大概有8种创建线程的方式,你知道吗? 继承Th ...

  4. java多线程系列7-停止线程

    本文主要总结在java中停止线程的方法 在java中有以下三种方法可以终止正在运行的线程: 1.使用退出标志 2.使用stop方法强行终止线程,但是不推荐,因为stop和suspend.resume一 ...

  5. java线程系列之三(线程协作)

    本文来自:高爽|Coder,原文地址:http://blog.csdn.net/ghsau/article/details/7433673,转载请注明. 上一篇讲述了线程的互斥(同步),但是在很多情况 ...

  6. java多线程系列六、线程池

    一. 线程池简介 1. 线程池的概念: 线程池就是首先创建一些线程,它们的集合称为线程池. 2. 使用线程池的好处 a) 降低资源的消耗.使用线程池不用频繁的创建线程和销毁线程 b) 提高响应速度,任 ...

  7. Java多线程系列四——控制线程执行顺序

    假设有线程1/线程2/线程3,线程3必须在线程1/线程2执行完成之后开始执行,有两种方式可实现 Thread类的join方法:使宿主线程阻塞指定时间或者直到寄生线程执行完毕 CountDownLatc ...

  8. (Java多线程系列九)线程池

    线程池 1.什么是线程池 线程池是指在初始化一个多线程应用程序过程中创建一个线程集合,然后在需要执行新的任务时重用这些线程而不是新建一个线程.线程池中线程的数量通常取决于可用内存数量和应用程序的需求. ...

  9. JAVA虚拟机系列文章

    本系列文章主要记录自己在学习<深入理解Java虚拟机-JVM高级特性与最佳实践>的知识点总结,文章内容都是基于周志明所著书籍的总结. 1.Java内存区域与溢出 2.垃圾收集器与内存分配策 ...

  10. 深入java集合系列文章

    搞懂java的相关集合实现原理,对技术上有很大的提高,网上有一系列文章对java中的集合做了深入的分析, 先转载记录下 深入Java集合学习系列 Java 集合系列目录(Category) HashM ...

随机推荐

  1. Hibernate5笔记9--Hibernate注解式开发

    Hibernate注解式开发: (1)注解式开发的注意点: Hibernate中使用注解,主要是为了替代映射文件,完成“类到表,属性到字段”的映射.  JPA提供了一套功能强大的注解.Hibernat ...

  2. Strusts2笔记6--拦截器

    拦截器: Struts2的大多数核心功能都是通过拦截器实现的.拦截器之所以称之为“拦截器”,是因为它可以在执行Action之前或之后拦截下用户请求,执行一些操作,以增强Action方法的功能. Str ...

  3. 10 Useeful Tips for Writing Effective Bash Scripts in Linux

    1.Always Use Comments in Scripts2.Make a Scripts exit When Fails    Sometimes bash may continue to e ...

  4. jQuery Validate自定义金钱验证,是否为金额格式,保留两位小数,并支持千分制货币格式

    //自定义函数实现 isMoney: function (value, element){ // return this.optional(element) || /(^[1-9]([0-9]+)?( ...

  5. ASP .Net Core系统部署到 CentOS7 64 具体方案

    .Net Core 部署到 CentOS7 64 位系统中的步骤 1.安装工具 1.apache 2..Net Core(dotnet-sdk-2.0) 3.Supervisor(进程管理工具,目的是 ...

  6. C实现线程池

    简介:这里使用linux下的互斥锁和条件变量实现了一个线程池.代码由一个未知作者完成,第二任作者补充优化. 本人仅仅是做了一些注释工作. 代码如下: /*! .h */ #include <st ...

  7. 本地删除文件,git远程不同步删除

    git add -a 或 git add * 它能stages所有文件,包括之前删除的痕迹 git add . 只能stages新文件和被修改的文件,不会stages已被删除的文件 步骤如下: 1) ...

  8. element-ui 2.7.2版本使用 表格展开行 功能遇到的奇葩问题?

    在使用 element-ui 2.7.2版本的时候报下面的错误: [Vue warn]: Error in callback for watcher "data": "E ...

  9. 提高eclipse使用效率(一)--使用快捷键

    编辑代码常用快捷键 格式化代码的快捷键 Ctrl + Shift + F 格式化缩进的快捷键是 Ctrl + I,只能对选中的文本进行缩进 删除一行的快捷键是 Ctrl + D 当前窗口最大化最小化切 ...

  10. 【LOJ】#2064. 「HAOI2016」找相同字符

    题解 做后缀自动机题要一点脑洞,脑洞一开,就过了 我们显然要拿第二个串跑第一个串的后缀自动机 我们可以求出第二个串每个位置匹配到的节点,和匹配的长度L 那么我们统计一个后缀树上的根缀和,表示这样个节点 ...