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个接口, ...
随机推荐
- iOS学习笔记17-FMDB
上一节我已经介绍了SQLite的简单使用,不了解的可以提前去看一下iOS学习笔记16-数据库SQLite,这节我们来讲下FMDB. 一.FMDB介绍 FMDB是一种第三方的开源库,FMDB就是对SQL ...
- 常州模拟赛d4t3 字符串划分
题目描述 给你一串由小写字母组成的字符串,希望你把它划分成一些小段,使得每一小段字符串中的字母 都不相同,并且希望分的段数尽量少. 然后,把这些小段按字典序排序后输出,中间由一个空格分隔. 例如:字符 ...
- Aragorn's Story(hdu3966)
题意:给一棵树,并给定各个点权的值,然后有3种操作: I C1 C2 K: 把C1与C2的路径上的所有点权值加上K D C1 C2 K:把C1与C2的路径上的所有点权值减去K Q C:查询节点编号为C ...
- 【Tyvj1982】武器分配(费用流)
题意:有N个人要从A个物品中各取一个,B个物品中各取一个,选取第i个A类物品和第j个B类物品的费用是(a[i]-b[j])^2 求最小总花费 n<=a,b<=80 a[i],b[i]< ...
- msp430项目编程60
msp430综合项目---扩展项目八60 1.电路工作原理 2.代码(显示部分) 3.代码(功能实现) 4.项目总结
- openssl搭建双向认证https
http://www.barretlee.com/blog/2015/10/05/how-to-build-a-https-server/ http://blog.163.com/fangjinbao ...
- python多线程实践小结
参考:http://www.cnblogs.com/tqsummer/archive/2011/01/25/1944771.html #!/usr/bin/env python import sys ...
- Idea Failed to read artifact descriptor for xx:jar:unknown
网上的解决方案: 根据网上说明添加了maven命令clean compile install -Dmaven.test.skip=true,与我遇到的问题不同 有的方法猜测可以通过,但是没时间测试了 ...
- 6.JAVA语言基础部分--数据库操作
操作数据数据流程:得到Connecnt->获取Statement对象->执行sql语句返回ResultSet 1.通过DriverManager.getConnection("j ...
- for 循环进化史
ECMAScript 6已经逐渐普及,经过二十多年的改进,很多功能也有了更成熟的语句,比如 for 循环 这篇博客将介绍一下从最初的 for 循环,到 ES6 的 for-of 等四种遍历方法 先定义 ...