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);
}
}
最新文章
- sql 触发器删除操作
- 计算机常用dos命令
- css3部分选择器整理
- java 27 - 8 反射之 通过反射来设置某个对象的某个属性为指定值
- Web API 接口
- paip.提升用户体验--radio图片选择器 easyui 实现..
- paip . 解决spring No unique bean of type [com.mijie.homi.search.service.index.MoodUserIndexService]
- 指针类型(C# 编程指南)
- 模板-->;中国剩余定理[互质版本]
- WebApi2官网学习记录---BSON
- 警告框和操作表(IOS开发)
- python chanllenge题解
- 【阿里聚安全&#183;安全周刊】500万台Android设备受感染|YouTube封杀枪支组装视频
- vue关闭代码检查eslint
- NLP入门(三)词形还原(Lemmatization)
- 1、通过eureka创建注册中心
- mysql 设置、更改、找回密码
- 线段树 || BZOJ1756: Vijos1083 小白逛公园 || P4513 小白逛公园
- JPEG
- # 20155214 2016-2017-2 《Java程序设计》第8周学习总结