Java,多个线程对同一个数据源的访问
当多个线程对同一个数据源进行访问时,应对线程同步或加锁。
为何?举个简单的例子:有一个共享的数据源dataSource,其值为0。有两个线程,Thread1和Thread2。
Thread1的任务是将dataSource连续自增10次,
Thread2的任务是将dataSource连续自减10次,
当两个线程的任务都完成时,最终的dataSource的值应为0,事实上,可能不为0,请看示例1:
import static java.lang.System.out;
public class LockTest1
{
private static int dataSource;
private static class Task1 implements Runnable
{
public void run()
{
for (int i = 0; i < 10; ++i)
{
out.printf("Task1 --- dataSource: %d\n", dataSource);
int t = dataSource + 1;
try
{
Thread.sleep(1);
}
catch (InterruptedException ex)
{
ex.printStackTrace();
}
finally
{
dataSource = t;
}
}
}
}
private static class Task2 implements Runnable
{
public void run()
{
for (int i = 0; i < 10; ++i)
{
out.printf("Task2 --- dataSource: %d\n", dataSource);
int t = dataSource - 1;
try
{
Thread.sleep(10);
dataSource = t;
}
catch (InterruptedException ex)
{
ex.printStackTrace();
}
finally
{
dataSource = t;
}
}
}
}
public static void main(String[] args) throws InterruptedException
{
Thread thread1 = new Thread(new Task1());
Thread thread2 = new Thread(new Task2());
thread1.start();
thread2.start();
Thread.sleep(1000);
out.printf("The value of dataSource is %d.", dataSource);
}
}
import static java.lang.System.out;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class LockTest2
{
private static int dataSource;
private static ReentrantReadWriteLock.WriteLock lock = new ReentrantReadWriteLock().writeLock();
private static class Task1 implements Runnable
{
public void run()
{
lock.lock();
for (int i = 0; i < 10; ++i)
{
int t = dataSource + 1;
out.printf("Task1 --- 自增前 --- dataSource: %d\n", dataSource);
try
{
Thread.sleep(1);
}
catch (InterruptedException ex)
{
ex.printStackTrace();
}
finally
{
dataSource = t;
out.printf("Task1 --- 自增后 --- dataSource: %d\n", dataSource);
}
}
lock.unlock();
}
}
private static class Task2 implements Runnable
{
public void run()
{
lock.lock();
for (int i = 0; i < 10; ++i)
{
out.printf("Task2 --- 自增前 --- dataSource: %d\n", dataSource);
int t = dataSource - 1;
try
{
Thread.sleep(10);
dataSource = t;
}
catch (InterruptedException ex)
{
ex.printStackTrace();
}
finally
{
dataSource = t;
out.printf("Task2 --- 自增后 --- dataSource: %d\n", dataSource);
}
}
lock.unlock();
}
}
public static void main(String[] args) throws InterruptedException
{
Thread thread1 = new Thread(new Task1());
Thread thread2 = new Thread(new Task2());
thread1.start();
thread2.start();
Thread.sleep(300);
//睡眠一段时间,确保thread1和thread2执行完毕后再打印dataSource的值
out.printf("dataSource的值为%d.", dataSource);
}
}
Java,多个线程对同一个数据源的访问的更多相关文章
- 第36节:Java当中的线程
Java当中的线程 Java当中的线程,进程和线程的关系?进程就是线程吗?不是的.线程的运行,和方法. 多线程和多进程,多进程为在操作系统中同时进行多个应用程序,如你的电脑可以同时听音乐,同时上网,手 ...
- java多线程之线程安全
线程安全和非线程安全是多线程的经典问题,非线程安全会在多个线程对同一个对象并发访问时发生. 注意1: 非线程安全的问题存在于实例变量中,如果是方法内部的私有变量,则不存在非线程安全问题. 实例变量是对 ...
- Java多线程 3 线程同步
在之前,已经学习到了线程的创建和状态控制,但是每个线程之间几乎都没有什么太大的联系.可是有的时候,可能存在多个线程多同一个数据进行操作,这样,可能就会引用各种奇怪的问题.现在就来学习多线程对数据访问的 ...
- JAVA中的线程安全与非线程安全
原文:http://blog.csdn.net/xiao__gui/article/details/8934832 ArrayList和Vector有什么区别?HashMap和HashTable有什么 ...
- Java面试题-线程安全
1. 什么叫线程安全?servlet是线程安全吗? 答:如果你的代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码.如果每次运行结果和单线程运行的结果是一样的,而且其他 ...
- Java并发3-多线程面试题
1) 什么是线程? 线程是操作系统能够进行运算调度的最小单位,它被包含在进程之中,是进程中的实际运作单位.程序员可以通过它进行多处理器编程,你可以使用多线程对运算密集型任务提速. 2) 线程和进程有什 ...
- Java中的线程Thread总结
首先来看一张图,下面这张图很清晰的说明了线程的状态与Thread中的各个方法之间的关系,很经典的! 在Java中创建线程有两种方法:使用Thread类和使用Runnable接口. 要注意的是Threa ...
- Java值创建线程的两种方式对比
在Java中创建线程的方式有两种,第一种是直接继承Thead类,另一种是实现Runable接口.那么这两种方式孰优孰劣呢? 采用继承Thead类实现多线程: 优势:编写简单,如果需要访问当前线程,只需 ...
- Java多线程之线程其他类
Java多线程之线程其他类 实际编码中除了前面讲到的常用的类之外,还有几个其他类也有可能用得到,这里来统一整理一下: 1,Callable接口和Future接口 JDK1.5以后提供了上面这2个接口, ...
随机推荐
- [luoguP2331] [SCOI2005]最大子矩阵(DP)
传送门 orz不会做... 一个好理解的做法(n^3*k): 分n=1和n=2两种情况考虑. n=1时,预处理出前缀和sum[]. 设f[i][j]为到达第i格,已经放了j个子矩阵的最大和, 那么每次 ...
- 【DFS序+线段树区间更新区间求最值】HDU 5692 Snacks
http://acm.hdu.edu.cn/showproblem.php?pid=5692 [思路] 每更新一个点,子树的所有结点都要更新,所以是区间更新 每查询一个点,子树的所有结点都要查询,所以 ...
- tomcat设置去项目路径
1. 新建一个目录专门用于存放工程, 如: G:\apache-tomcat-6.0.20\project 2. 将工程存放到以上目录下:即:G:\apache-tomcat-6.0.20\proje ...
- Mysql安装及自动化部署脚本方案
一.简介 数据库(Database)是按照数据结构来组织.存储和管理数据的仓库, 每个数据库都有一个或多个不同的API用于创建,访问,管理,搜索和复制所保存的数据. 我们也可以将数据存储在文件中,但是 ...
- 标准C程序设计七---15
Linux应用 编程深入 语言编程 标准C程序设计七---经典C11程序设计 以下内容为阅读: <标准C程序设计>(第7版) 作者 ...
- 使用 ftrace 调试 Linux 内核,第 2 部分
ftrace 操作概述 使用 ftrace 提供的跟踪器来调试或者分析内核时需要如下操作: 切换到目录 /sys/kernel/debug/tracing/ 下 查看 available_tracer ...
- MongoDB GridFS(命令行+php操作)
一.GridFS是什么 & 为什么需要它 我们知道目前MongoDB的BSON文件最大只能是16M,也就是说单个文档最多只能存储16M的数据,那么如果需要MongoDB存储超过16M的大文件该 ...
- 使用Sharesdk实现第三方平台登录(qq,新浪微博)
首先到sharesdk开放píng台下载demo ,以下要用到的文件来自于 simple里面 第一步:导入官方的jar包 第二步:添加ShareSDK.xml文件并修改相关píng台key 第 ...
- CF 2018 Battle of Brains GYM 102062 F
https://codeforces.com/gym/102062/attachments/download/8213/2018-battle-of-brains-en.pdf https://cod ...
- Maven错误 diamond operator is not supported in -source 1.5 (use -source 7 or higher to enable diamond operator)问题解决
如果在Maven构建时出现: diamond operator is not supported in -source 1.5 (use -source 7 or higher to enable d ...