1. package com.sxt.syn;
  2. /**
  3. * 线程安全: 在并发时保证数据的正确性、效率尽可能高
  4. * synchronized
  5. * 1、同步方法
  6. * 2、同步块
  7. *
  8. *
  9. */
  10. public class SynBlockTest03 {
  11.  
  12. public static void main(String[] args) {
  13. //一份资源
  14. SynWeb12306 web =new SynWeb12306();
  15. //多个代理
  16. new Thread(web,"码畜").start();
  17. new Thread(web,"码农").start();
  18. new Thread(web,"码蟥").start();;
  19. }
  20.  
  21. }
  22.  
  23. class SynWeb12306 implements Runnable{
  24. //票数
  25. private int ticketNums =10;
  26. private boolean flag = true;
  27. @Override
  28. public void run() {
  29. while(flag) {
  30. try {
  31. Thread.sleep(100);
  32. } catch (InterruptedException e) {
  33. e.printStackTrace();
  34. }
  35. test5();
  36. }
  37. }
  38. //线程安全:尽可能锁定合理的范围(不是指代码 指数据的完整性)
  39. //double checking
  40. public void test5() {
  41. if(ticketNums<=0) {//考虑的是没有票的情况
  42. flag = false;
  43. return ;
  44. }
  45. synchronized(this) {
  46. if(ticketNums<=0) {//考虑最后的1张票
  47. flag = false;
  48. return ;
  49. }
  50. //模拟延时
  51. try {
  52. Thread.sleep(200);
  53. } catch (InterruptedException e) {
  54. e.printStackTrace();
  55. }
  56. System.out.println(Thread.currentThread().getName()+"-->"+ticketNums--);
  57. }
  58. }
  59. //线程不安全 范围太小锁不住
  60. public void test4() {
  61. synchronized(this) {
  62. if(ticketNums<=0) {
  63. flag = false;
  64. return ;
  65. }
  66. }
  67. //模拟延时
  68. try {
  69. Thread.sleep(200);
  70. } catch (InterruptedException e) {
  71. e.printStackTrace();
  72. }
  73. System.out.println(Thread.currentThread().getName()+"-->"+ticketNums--);
  74.  
  75. }
  76. //线程不安全 ticketNums对象在变
  77. public void test3() {
  78. synchronized((Integer)ticketNums) {
  79. if(ticketNums<=0) {
  80. flag = false;
  81. return ;
  82. }
  83. //模拟延时
  84. try {
  85. Thread.sleep(200);
  86. } catch (InterruptedException e) {
  87. e.printStackTrace();
  88. }
  89. System.out.println(Thread.currentThread().getName()+"-->"+ticketNums--);
  90. }
  91. }
  92. //线程安全 范围太大 -->效率低下
  93. public void test2() {
  94. synchronized(this) {
  95. if(ticketNums<=0) {
  96. flag = false;
  97. return ;
  98. }
  99. //模拟延时
  100. try {
  101. Thread.sleep(200);
  102. } catch (InterruptedException e) {
  103. e.printStackTrace();
  104. }
  105. System.out.println(Thread.currentThread().getName()+"-->"+ticketNums--);
  106. }
  107. }
  108.  
  109. //线程安全 同步
  110. public synchronized void test1() {
  111. if(ticketNums<=0) {
  112. flag = false;
  113. return ;
  114. }
  115. //模拟延时
  116. try {
  117. Thread.sleep(200);
  118. } catch (InterruptedException e) {
  119. e.printStackTrace();
  120. }
  121. System.out.println(Thread.currentThread().getName()+"-->"+ticketNums--);
  122. }
  123. }

避免死锁:不要在同一个代码块中,同时持有多个对象的锁

多线程--同步--方法块和同步块synchronized的更多相关文章

  1. JAVA之旅(十三)——线程的安全性,synchronized关键字,多线程同步代码块,同步函数,同步函数的锁是this

    JAVA之旅(十三)--线程的安全性,synchronized关键字,多线程同步代码块,同步函数,同步函数的锁是this 我们继续上个篇幅接着讲线程的知识点 一.线程的安全性 当我们开启四个窗口(线程 ...

  2. 线程同步 synchronized 同步代码块 同步方法 同步锁

    一 同步代码块 1.为了解决并发操作可能造成的异常,java的多线程支持引入了同步监视器来解决这个问题,使用同步监视器的通用方法就是同步代码块.其语法如下: synchronized(obj){ // ...

  3. 为什么wait()方法要放在同步块

    回顾一下,如果wait()方法不在同步块中,代码的确会抛出异常: public class WaitInSyncBlockTest { @Test public void test() { try { ...

  4. 阿里面试题,为什么wait()方法要放在同步块中?

    某天我在***的时候,突然有个小伙伴微信上说:“哥,阿里面试又又挂了,被问到为什么wait()方法要放在同步块中,没答出来!” 我顿时觉得**一紧,仔细回顾一下,如果wait()方法不在同步块中,代码 ...

  5. “全栈2019”Java多线程第二十一章:同步代码块产生死锁的例子

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...

  6. “全栈2019”Java多线程第十八章:同步代码块双重判断详解

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...

  7. 多线程学习-基础( 十)一个synchronized(){/*代码块*/}简单案例分析

    一.提出疑惑 上一篇文章中,分析了synchronized关键字的用法.但是好像遗漏了一种情况. 那就是: synchronized(obj){/*同步块代码*/} 一般有以下几种情况: (1)syn ...

  8. 牛客网Java刷题知识点之什么是代码块、普通代码块、静态代码块、同步代码块、构造代码块以及执行顺序

    不多说,直接上干货! 这种形式的程序段我们将其称之为代码块,所谓代码块就是用大括号({})将多行代码封装在一起,形成一个独立的数据体,用于实现特定的算法.一般来说代码块是不能单独运行的,它必须要有运行 ...

  9. Java基础学习笔记: 多线程,线程池,同步锁(Lock,synchronized )(Thread类,ExecutorService ,Future类)(卖火车票案例)

    多线程介绍 学习多线程之前,我们先要了解几个关于多线程有关的概念.进程:进程指正在运行的程序.确切的来说,当一个程序进入内存运行,即变成一个进程,进程是处于运行过程中的程序,并且具有一定独立功能. 线 ...

  10. About 静态代码块,普通代码块,同步代码块,构造代码块和构造函数的纳闷

    构造函数用于给对象进行初始化,是给与之对应的对象进行初始化,它具有针对性,函数中的一种.特点:1:该函数的名称和所在类的名称相同.2:不需要定义返回值类型.3:该函数没有具体的返回值.记住:所有对象创 ...

随机推荐

  1. Django 之 restframework 解析器源码分析

    解析器分类: 1. JSONPaser ----> 解析 JSON-serialized data (解析JSON序列化的数据) 2.FormParser ---->解析form 表单中 ...

  2. python中的exec()函数和eval()函数

    exec()函数 exec函数用于执行存储在字符串中的python语句 >>> exec("x=1") >>> x 但有时候,直接这样执行可能会 ...

  3. 【Linux】Linux下安装RabbitMQ服务

    一.安装步骤 1)安装erlang yum install -y erlang2)安装rabbitmq-serveryum install -y rabbitmq-server3)开启rabbitmq ...

  4. filter-grok,dissect匹配数据

    Grok(正则捕获).Dissect(切分): grok使用正则匹配来提取非结构化日志数并据解析为结构化和可查询的内容. dissect使用多种定界符(非数字和字母的符号,split只能一次只能使用一 ...

  5. backtrace() returns only one stack frame

    参考: 在Linux中如何利用backtrace信息解决程序崩溃的问题 linux 打印堆栈方法 https://devtalk.nvidia.com/default/topic/987279/jet ...

  6. Httpd服务入门知识-Httpd服务常见配置案例之基于用户账号实现访问控制

    Httpd服务入门知识-Httpd服务常见配置案例之基于用户账号实现访问控制 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.基于用户的访问控制概述 认证质询: WWW-Auth ...

  7. Socket网络编程-IO各种概念及多路复用

    Socket网络编程-IO各种概念及多路复用 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.操作系统相关知识 1>.同步和异步  函数或方法被调用的时候,调用者是否得到最 ...

  8. 目标检测论文解读5——YOLO v1

    背景 之前热门的目标检测方法都是two stage的,即分为region proposal和classification两个阶段,本文是对one stage方法的初次探索. 方法 首先看一下模型的网络 ...

  9. Unity 渲染教程(五):多个光源

    https://www.jianshu.com/p/c1a9a5d27765 对每个物体渲染多个光源的光照效果. 支持不同的光源类型. 使用光源cookie. 计算顶点光照. 在光照计算中添加球面谐波 ...

  10. spark的RDDAPI总结

    下面是RDD的基础操作API介绍: 操作类型 函数名 作用 转化操作 map() 参数是函数,函数应用于RDD每一个元素,返回值是新的RDD flatMap() 参数是函数,函数应用于RDD每一个元素 ...