如果有多个线程在同时运行,而这些线程可能会同时运行这段代码。程序每次运行结果和单线程运行的结果是一样
的,而且其他的变量的值也和预期的是一样的,就是线程安全的。

  通过卖火车票的例子

火车站要卖票,我们模拟卖票过程。假设座位共100个,
我们来模拟售票窗口,实现多个窗口同时卖票
需要窗口,采用线程对象来模拟;需要票,Runnable接口子类来模拟

未加锁前:

public class RunnableImpl implements  Runnable {
//定义总票数
private int ticket=100;
@Override
public void run() {
while (true) {

if (ticket > 0) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "正在卖出" + ticket + "张票");
//票数减少
ticket--;
}
}
}
}
出现线程安全问题

线程安全问题都是由全局变量及静态变量引起的。若每个线程中对全局变量、静态变量只有读操作,而无写
操作,一般来说,这个全局变量是线程安全的;若有多个线程同时执行写操作,一般都需要考虑线程同步,
否则的话就可能影响线程安全

模拟票(通过synchronized线程同步):

    synchronized(同步锁){
需要同步操作的代码
}

public class RunnableImpl implements  Runnable {
//定义总票数
private int ticket=100;
//加锁
Object Object= new Object();
@Override
public void run() {
while (true) {
synchronized (Object) {
if (ticket > 0) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "正在卖出" + ticket + "张票");
//票数减少
ticket--;
}
}
}
}
}
售票测试类:
public class sellTicket {
public static void main( String[] args ) {
RunnableImpl runnable = new RunnableImpl();
Thread thread0 = new Thread(runnable);
Thread thread1 = new Thread(runnable);
Thread thread2 = new Thread(runnable);
//调用start方法
thread0.start();
thread1.start();
thread2.start();
}
}

线程安全

使用lock锁的方式实现线程安全:
d
java.util.concurrent.locks.Lock 机制提供了比synchronized代码块和synchronized方法更广泛的锁定操作,
同步代码块/同步方法具有的功能Lock都有,除此之外更强大,更体现面向对象。
Lock锁也称同步锁,加锁与释放锁方法化了,如下:
  public void lock() :加同步锁。
  public void unlock() :释放同步锁。
使用如下:

 //定义总票数
private int ticket = 100;
//使用锁
Lock lock = new ReentrantLock();
@Override
public void run() {
while (true) {
//加锁
lock.lock();
if (ticket > 0) {
try {
Thread.sleep(10);
System.out.println(Thread.currentThread().getName() + "正在卖出" + ticket + "张票");
//票数减少
ticket--;
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
lock.unlock();
}
}
}

}
}

最新文章

  1. [8.1] Triple Step
  2. 【html+css】关于页面布局中遇到的问题记录
  3. Wix 安装部署教程(八) 自动生成XML小工具
  4. 主机宝(zhujibao) /a/apps/zhujibao/manager/apps/config/config.php no-password Login Vulnerabilities Based On Default cookie Verification From Default File
  5. [Spring MVC] - Spring MVC环境搭建
  6. Docker 简单入门
  7. SQL语句的执行计划(oracle表的三种链接方式)
  8. 如何将一个 ASP.NET MVC 4 和 Web API 项目升级到 ASP.NET MVC 5 和 Web API 2
  9. Hibernate数据库对象的创建与导出
  10. C与C++中的const
  11. Spring:启动项目时加载数据库数据(总结)
  12. 二维离散平稳小波重构iswt2
  13. 20155215 2016-2017-2 《Java程序设计》第5周学习总结
  14. [转载]常见slave 延迟原因以及解决方法
  15. dva.js 用法总结
  16. [Luogu 3901]Difference
  17. ●BZOJ 3143 [Hnoi2013]游走
  18. The open source JavaScript graphing library that powers Plotly
  19. 【Selenium-WebDriver自学】Selenium-IDE用户扩展(七)
  20. .33-浅析webpack源码之doResolve事件流(5)

热门文章

  1. Centos8 Tomcat 开机自启配置
  2. OI卷题记录
  3. Vulhub-DC-3靶场
  4. Git8.3k星,十万字Android主流开源框架源码解析,必须盘
  5. 【Unity3D】Android App Bundle(aab)打包上架Google Play介绍
  6. 如何远程调试自定义开发的Flume应用
  7. Linux进程间通信方式--信号,管道,消息队列,信号量,共享内存
  8. MySQL数据库优化(2)
  9. 【原创】利用动态二进制加密实现新型一句话木马之PHP篇
  10. DVWA-全等级文件包含