java线程系列文章之一(线程的安全性)
本文来自:高爽|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线程系列文章之一(线程的安全性)的更多相关文章
- java nio系列文章
java nio系列教程 基于NIO的Client/Server程序实践 (推荐) java nio与并发编程相关电子书籍 (访问密码 48dd) 理解NIO nio学习记录 图解ByteBuff ...
- 线程系列08,实现线程锁的各种方式,使用lock,Montor,Mutex,Semaphore以及线程死锁
当涉及到多线程共享数据,需要数据同步的时候,就可以考虑使用线程锁了.本篇体验线程锁的各种用法以及线程死锁.主要包括: ※ 使用lock处理数据同步※ 使用Monitor.Enter和Monitor.E ...
- 死磕 java线程系列之创建线程的8种方式
(手机横屏看源码更方便) 问题 (1)创建线程有哪几种方式? (2)它们分别有什么运用场景? 简介 创建线程,是多线程编程中最基本的操作,彤哥总结了一下,大概有8种创建线程的方式,你知道吗? 继承Th ...
- java多线程系列7-停止线程
本文主要总结在java中停止线程的方法 在java中有以下三种方法可以终止正在运行的线程: 1.使用退出标志 2.使用stop方法强行终止线程,但是不推荐,因为stop和suspend.resume一 ...
- java线程系列之三(线程协作)
本文来自:高爽|Coder,原文地址:http://blog.csdn.net/ghsau/article/details/7433673,转载请注明. 上一篇讲述了线程的互斥(同步),但是在很多情况 ...
- java多线程系列六、线程池
一. 线程池简介 1. 线程池的概念: 线程池就是首先创建一些线程,它们的集合称为线程池. 2. 使用线程池的好处 a) 降低资源的消耗.使用线程池不用频繁的创建线程和销毁线程 b) 提高响应速度,任 ...
- Java多线程系列四——控制线程执行顺序
假设有线程1/线程2/线程3,线程3必须在线程1/线程2执行完成之后开始执行,有两种方式可实现 Thread类的join方法:使宿主线程阻塞指定时间或者直到寄生线程执行完毕 CountDownLatc ...
- (Java多线程系列九)线程池
线程池 1.什么是线程池 线程池是指在初始化一个多线程应用程序过程中创建一个线程集合,然后在需要执行新的任务时重用这些线程而不是新建一个线程.线程池中线程的数量通常取决于可用内存数量和应用程序的需求. ...
- JAVA虚拟机系列文章
本系列文章主要记录自己在学习<深入理解Java虚拟机-JVM高级特性与最佳实践>的知识点总结,文章内容都是基于周志明所著书籍的总结. 1.Java内存区域与溢出 2.垃圾收集器与内存分配策 ...
- 深入java集合系列文章
搞懂java的相关集合实现原理,对技术上有很大的提高,网上有一系列文章对java中的集合做了深入的分析, 先转载记录下 深入Java集合学习系列 Java 集合系列目录(Category) HashM ...
随机推荐
- Oracle 11G R2 RAC中的scan ip 的用途和基本原理【转】
Oracle 11G R2 RAC增加了scan ip功能,在11.2之前,client链接数据库的时候要用vip,假如你的cluster有4个节点,那么客户端的tnsnames.ora中就对应有四个 ...
- IIS错误:在唯一密钥属性“fileExtension”设置为“.mp4”时,无法添加类型为“mimeMap”的重复集合项
之前的IIS配置中,.mp4类型的文件默认无法访问,所以个人在IIS7.5的mime类型中增加了.mp4的类型的支持,但问题是需要每台机器中增加这些设置,不利于团队协作,于是,只好将这些修改体现在代码 ...
- Windows 10安装uWSGI:不可行、失败了
Windows 10家庭中文版,Python 3.6.4,uwsgi-2.0.17.tar.gz,压缩工具-7-zip 提示:请不要和我一样尝试,浪费时间,去Linux上玩吧! 几个小时的安装经历 昨 ...
- 使用html+css+js实现日历与定时器,看看今天的日期和今天剩余的时间。
使用html+css+js实现日历与定时器,看看今天的日期和今天剩余的时间. 效果图: 哎,今天就又这么过去了,过的可真快 . 代码如下,复制即可使用: <!DOCTYPE html> & ...
- delphi 获取一个字符占用几个字节,方法
- SP_attach_db 添加数据库文件
SP_attach_db 用法如下: EXEC SP_attach_db @dbname = N'目标数据库名', //这是你要引入后的数据库名. ...
- MySQL学习笔记:计算机服务中找不到MySQL服务
不知道什么原因,连接了远程服务器之后,本地服务就连接不上. 经排查,发现服务中的MySQL服务居然不见,一番搜索之后,在CMD中进入到MySQL安装目录的bin下执行以下语句: mysqld.exe ...
- Python SGMLParser 的1个BUG??
首先说一下,我用的是python 2.7,刚好在学Python,今天想去爬点图片当壁纸,但是当我用 SGMLParser 做 <img> 标签解析的时候,发现我想要的那部分根本没获取到,我 ...
- 关于利用GPG加解密的实验
GnuPG(GNU Privacy Guard,简称:GPG)为一款免费开源的使用非对称密钥加密(asymmetric cryptography)之软件,最初由Werner Koch开发,该软件使用非 ...
- MySQL慢查询优化
MySQL数据库是常见的两个瓶颈是CPU和I/O的瓶颈,CPU在饱和的时候一般发生在大量数据进行比对或聚合时.磁盘I/O瓶颈发生在装入数据远大于内存容量的时候,如果应用分布在网络上,那么查询量相当大的 ...