线程的生命周期:

什么情况会产生线程安全问题?
当多个线程同时共享同一个全局变量或静态变量,做写的操作时,可能会发生数据冲突问题,即产生线程安全问题。读的操作不会发生线程安全问题。

例子:上文中的卖票例子,假如产生阻塞:
1.问题:买票过程中出现了重票和错票–》出现了线程安全问题
2.原因:当某个线程操作车票的过程中,尚未操作完成时,其他线程也参与进来操作车票,导致车票信息出错。

    @Overridepublic void run() {//        int ticket = 100;while (true) {if (ticket > 0) {//线程安全问题出现try {Thread.sleep(100);//人为增加阻塞} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName() + "卖票:票号为" + ticket);ticket--;} else {break;}}

输出结果涵盖错误信息:

理想状态:

极端状态:

3.如何解决线程安全问题?
采用同步机制来解决,使用synchronized关键字/lock关键字。
当线程A在操作共享数据(ticket)时,其他进程不能参与进来,直到线程A操作完成时,其他线程才可以开始操作ticket。这种情况即使线程A出现了阻塞也不能被改变。
4.在Java中,我们通过同步机制,来解决线程安全问题

方式一:同步代码块:
1.synchronized(this)//针对实现Runnable接口创建多线程的方式,可以使用this充当同步监听器
2.synchronized(同步监视器){
需要被同步的代码/共享数据
}
3.synchronized (Window.class) {//针对继承Thread类的方式

Object obj = new Object();//Runnable接口的方式本身数据共享,但是继承Thread类的方式必须加staticpublic void run() {while (true) {synchronized (obj) {//synchronized (this) {//synchronized (Window.class) {//针对继承Thread类的方式if (ticket > 0) {//线程安全问题出现try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName() + "售票:票号为" + ticket);ticket--;} else {break;}}}
}

说明:1.操作共享数据的代码,即为需要被同步的代码
2.共享数据:多个线程共同操作的变量。如ticket
3.同步监视器:俗称:锁。任何一个类的对象,都可以充当锁。但是多个线程必须要共用同一把锁。

方式二:同步方法:
如果操作共享数据的代码完整的声明在一个方法中,可以将这个方法声明成同步的。
1.同步方法仍然设计到同步监视器,只是不需要我们显式的声明。
2.非静态的同步方法,同步监视器是:this //一般针对实现了Runnable接口的方式
3.静态的同步方法,同步监视器是:当前类本身 //一般针对继承了Thread类的方式
eg:

 private synchronized void show(){//针对实现了Runnable接口的方式
}
private static synchronized void show(){//针对继承了Thread类的方式
}

方式三:使用lock锁
比较常用的是ReentrantLock类,显式加锁,释放锁。
手动启动同步lock()/手动结束同步unlock()
eg:

    private ReentrantLock lock = new ReentrantLock();//空参默认false@Overridepublic void run() {while(true){try{//2.调用锁定方法lock()lock.lock();if(ticket > 0){//只是为了让阻塞概率变大try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName()+"售票:票号为"+ticket);ticket--;}else{break;}}finally{//3.调用解锁方法unlock()lock.unlock();}}}

5.同步的方式,解决了线程安全问题。
but操作同步代码时,只能有一个线程参与,其他线程等待。相当于是一个单线程的过程,效率低。

同步原理:

使用同步机制解决线程安全问题相关推荐

  1. 4种解决线程安全问题的方式

    前言 线程安全问题,在做高并发的系统的时候,是程序员经常需要考虑的地方.怎么有效的防止线程安全问题,保证数据的准确性?怎么合理的最大化的利用系统资源等,这些问题都需要充分的理解并运行线程.当然关于多线 ...

  2. 线程安全,线程同步,解决线程同步问题

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

  3. 如何解决线程安全问题?有几种方式?synchronized与lock有什么异同?

    1.谈谈你对同步代码块中同步监视器和共享数据的理解以及各自要求? 同步监视器:俗称锁.①任何一个类的对象都可以充当:②多个线程共用同一把锁. 共享数据:多个线程共同操作的数据. 2.什么情况会产生线程 ...

  4. 什么是线程安全问题 及怎么解决线程安全问题

    1.什么是线程安全问题 就是 多线程环境中 , 且存在数据共享 , 一个线程访问的共享 数据被其他线程修改了, 那么就发生了线程安全问题 , 整个访问过程中 , 无一共享的数据被其他线程修改了 就是线 ...

  5. Java解决线程安全问题

    文章目录 背景 1. 线程安全问题 1.1 什么是线程安全? 1.2 产生的原因 1.3 实例(买票超卖问题) 1.4 如何确定是否存在线程安全问题? 2. 如何解决线程安全问题? 2.1 不可变(I ...

  6. 多线程的创建方式和解决线程安全问题

    一  基本概念 ①程序(program)是为完成特定任务.用某种语言编写的一组指令的集合.即指一 段静态的代码,静态对象. ②进程(process)是程序的一次执行过程,或是正在运行的一个程序.是一个 ...

  7. 如何解决线程安全问题

    如何解决线程安全问题 怎么解决线程的安全问题呢? 基本上所有解决线程安全问题的方式都是采用"序列化临界资源访问"的方式,即在同一时刻只有一个线程操作临界资源,操作完了才能让其他线程 ...

  8. 【解决线程安全问题:通过Lock锁对象】

    [解决线程安全问题:通过Lock锁对象] 参考文章: (1)[解决线程安全问题:通过Lock锁对象] (2)https://www.cnblogs.com/zuixinxian/p/9570409.h ...

  9. java并发之如何解决线程安全问题

    java并发之如何解决线程安全问题 参考文章: (1)java并发之如何解决线程安全问题 (2)https://www.cnblogs.com/w2154/p/6637717.html 备忘一下.

最新文章

  1. matlab2013a vs2013 opencv2.4.8 编译TLD
  2. matlab画出周期为2的方波图形 傅立叶级数_高等数学系列R之四:傅立叶级数及变换...
  3. HTML期末作业-家乡网站
  4. RHEL6上课笔记之background_process_command
  5. 处理 git 合并冲突
  6. 资源监视工具 Glances
  7. css-元素居中方法总结
  8. 两万字详解MongoDB从入门到精通
  9. 独立看门狗及其实现的热启动
  10. NTP、PTP时间同步服务器(时钟系统)
  11. 设置代理后谷歌浏览器无法使用代理
  12. 基于图像识别的火灾探测技术
  13. 站在巨人的肩膀上(转载)
  14. pta:人民币与美元汇率兑换程序(python)
  15. 指尖菜谱App从0到1-项目开发准备
  16. recyclerView的滑动
  17. 智能服装:引爆2016智能穿戴新发展
  18. 五、从命令行管理文件
  19. easyUi input标签的失去焦点事件
  20. redis: WRONGTYPE Operation against a key holding the wrong kind of value

热门文章

  1. qt中关于坐标的说明
  2. JS DOM事件(常用消息、常用事件、addEventListener、removeEventListener)
  3. 应用netstat查看目标机TCP连接的状况
  4. python序列中是否包含某个元素
  5. 201312-5 I’m stuck!
  6. tslib编译使用方法
  7. Luogu P1122 最大子树和 树形DP
  8. python模块之 paramiko(转载)
  9. Windows 上 GitHub Desktop 的操作
  10. grid列的值格式化