多线程的锁有: synchronized 和 jdk1.5的Lock

先说synchronized的各种用法:

1. 使用任意同一对象做锁  (一定要是同一对象)

2. 使用this做锁

3. class字节码文件做锁

4. 静态同步代码块做锁    (原理其实就是:class字节码文件做锁)

5.非静态同步代码块做锁 (原理其实就是:使用this做锁)

任意对象做锁例子:

/*** @author: wangqinmin* @date : 2020/7/3* @description: 仰天大笑出门去,我辈岂是蓬蒿人*/
public class TicketRunnable implements Runnable {/*** 需求现在有100张火车票,有两个窗口同时抢火车票,请使用多线程模拟抢票效果。*/int tickets = 100;private Object obj = new Object();public void run() {while (tickets > 0) {try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}sale();}}public void sale() {/*** 使用任意、同一对象做锁*/synchronized (obj) {/*** 最后判断一下,还是因为有线程安全的问题。** 最后一张票卖完后,tickets = 0,但是这时候,最后一个等待的线程刚刚就就进来了,所以会得到100 - 0 + 1  ,结果为101的票,所以在这里判断一下。* 还有一个办法,就是在  while (tickets > 0) 之前就加 synchronized。* 但是使用synchronized最好包裹的代码很少,所以就这样写了。* 又如果在while那里就包裹了,多半这个代码直接就一个线程执行完了。*/if (tickets > 0) {System.out.println(Thread.currentThread().getName() + ",出售第" + (100 - tickets + 1) + "票");tickets--;}}}
}

this做锁的例子:

/*** @author: wangqinmin* @date : 2020/7/3* @description: 仰天大笑出门去,我辈岂是蓬蒿人*/
public class TicketRunnable implements Runnable {/*** 需求现在有100张火车票,有两个窗口同时抢火车票,请使用多线程模拟抢票效果。*/int tickets = 100;public void run() {while (tickets > 0) {try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}sale();}}public void sale() {/*** this做锁*/synchronized (this) {/*** 最后判断一下,还是因为有线程安全的问题。** 最后一张票卖完后,tickets = 0,但是这时候,最后一个等待的线程刚刚就就进来了,所以会得到100 - 0 + 1  ,结果为101的票,所以在这里判断一下。* 还有一个办法,就是在  while (tickets > 0) 之前就加 synchronized。* 但是使用synchronized最好包裹的代码很少,所以就这样写了。* 又如果在while那里就包裹了,多半这个代码直接就一个线程执行完了。*/if (tickets > 0) {System.out.println(Thread.currentThread().getName() + ",出售第" + (100 - tickets + 1) + "票");tickets--;}}}
}

class字节码文件做锁的例子:

/*** @author: wangqinmin* @date : 2020/7/3* @description: 仰天大笑出门去,我辈岂是蓬蒿人*/
public class TicketRunnable implements Runnable {/*** 需求现在有100张火车票,有两个窗口同时抢火车票,请使用多线程模拟抢票效果。*/int tickets = 100;private Object obj = new Object();public void run() {while (tickets > 0) {try {Thread.sleep(10);} catch (InterruptedException e) {e.printStackTrace();}sale();}}public void sale() {/*** class文件做锁*/synchronized (TicketRunnable.class) {/*** 最后判断一下,还是因为有线程安全的问题。** 最后一张票卖完后,tickets = 0,但是这时候,最后一个等待的线程刚刚就就进来了,所以会得到100 - 0 + 1  ,结果为101的票,所以在这里判断一下。* 还有一个办法,就是在  while (tickets > 0) 之前就加 synchronized。* 但是使用synchronized最好包裹的代码很少,所以就这样写了。* 又如果在while那里就包裹了,多半这个代码直接就一个线程执行完了。*/if (tickets > 0) {System.out.println(Thread.currentThread().getName() + ",出售第" + (100 - tickets + 1) + "票");tickets--;}}}
}

静态同步代码块做锁: (并证明原理为 字节码文件为锁)

/*** @author: wangqinmin* @date : 2020/7/3* @description: 仰天大笑出门去,我辈岂是蓬蒿人*/
public class TicketRunnable implements Runnable {/*** 需求现在有100张火车票,有两个窗口同时抢火车票,请使用多线程模拟抢票效果。* <p>* 使用静态变量*/private static int tickets = 100;private Object obj = new Object();public void run() {while (tickets > 0) {try {Thread.sleep(10);} catch (InterruptedException e) {e.printStackTrace();}if (tickets % 2 != 0) {synchronized (TicketRunnable.class) {if (tickets > 0) {System.out.println(Thread.currentThread().getName() + ",出售第" + (100 - tickets + 1) + "票");tickets--;}}} else {sale();}}}/*** 定义静态同步代码块* 在方法上,加上 static  和  synchronized。* <p>* 原理: 这个其实就是使用的字节码文件做锁。* <p>* 怎么证明呢 ? 可以写两个线程,一个使用字节码文件做锁,一个使用静态同步代码块,如果完成了同步功能,就证明静态同步代码快使用的是 字节码文件做锁。* <p>* 在工作中,不推荐使用静态同步锁,因为静态方法不会被回收。* 建议使用 非静态同步代码块做锁;*/public static synchronized void sale() {if (tickets > 0) {System.out.println(Thread.currentThread().getName() + ",出售第" + (100 - tickets + 1) + "票");tickets--;}}
}

非静态同步代码块做锁:(并证明原理为: this做锁)

/*** @author: wangqinmin* @date : 2020/7/3* @description: 仰天大笑出门去,我辈岂是蓬蒿人*/
public class TicketRunnable implements Runnable {/*** 需求现在有100张火车票,有两个窗口同时抢火车票,请使用多线程模拟抢票效果。* <p>* 使用静态变量*/private int tickets = 100;private Object obj = new Object();public void run() {while (tickets > 0) {try {Thread.sleep(10);} catch (InterruptedException e) {e.printStackTrace();}/*** 使用判断,证明非静态同步代码快使用的是this锁*/if (tickets % 2 != 0) {synchronized (this) {if (tickets > 0) {System.out.println(Thread.currentThread().getName() + ",出售第" + (100 - tickets + 1) + "票");tickets--;}}} else {sale();}}}/*** 定义非静态同步代码块* 在方法上,加上 synchronized。* <p>* 原理: 这个其实就是使用的this锁。* <p>* 怎么证明呢 ? 可以写两个线程,一个使用this锁,一个使用非静态同步代码块,如果完成了同步功能,就证明非静态同步代码快使用的是this锁。*/public synchronized void sale() {if (tickets > 0) {System.out.println(Thread.currentThread().getName() + ",出售第" + (100 - tickets + 1) + "票");tickets--;}}
}

上面都是各种做锁的例子, 这里是创建多线程,并调用:

/*** @author: wangqinmin* @date : 2020/7/3* @description: 仰天大笑出门去,我辈岂是蓬蒿人*/
public class Test {public static void main(String[] args) {TicketRunnable ticket = new TicketRunnable();Thread t1 = new Thread(ticket, "窗口1");Thread t2 = new Thread(ticket, "窗口2");t1.start();t2.start();}
}

多线程基础讲解五: synchronized使用相关推荐

  1. JAVA多线程基础篇-关键字synchronized

    1.概述 syncronized是JAVA多线程开发中一个重要的知识点,涉及到多线程开发,多多少少都使用过.那么syncronized底层是如何实现的?为什么加了它就能实现资源串行访问?本文将基于上述 ...

  2. 多线程基础(五)NSThread线程通信

    5.多线程基础 线程间通信 什么叫线程间通信 在一个进程中,线程往往不是孤立存在的,多个线程之间需要经常进行通信 线程间通信的体现 1个线程传递数据给另一个线程 在1个线程中执行完特定任务后, 线程间 ...

  3. 一篇文章弄懂Java多线程基础和Java内存模型

    文章目录 一.多线程的生命周期及五种基本状态 二.Java多线程的创建及启动 1.继承Thread类,重写该类的run()方法 2.通过实现Runnable接口创建线程类 3.通过Callable和F ...

  4. java多线程基础学习[狂神说java-多线程笔记]

    java多线程基础学习 一.线程简介 1.类比 2.程序进程线程 3.线程的核心概念 二.线程的实现(重点) 调用方法与调用多线程的区别 Thread 类 1.thread使用方法 2. 代码实现 3 ...

  5. JAVA并发之多线程基础(2)

    除了我们经常用的synchronized关键字(结合Object的wait()和notify()使用)之外,还有对应的上篇文章讲到的方法JAVA并发之多线程基础(1)之外,我们日常中使用到最多的也就是 ...

  6. JAVA并发之多线程基础(5)

    上面介绍了并发编程中的栅栏等JAVA并发之多线程基础(4) .通过唯一的一个终点线来帮助确定线程是多晚开始执行下一次操作. LockSupport 提供了一个比较底层的线程挂起操作.有点类似于susp ...

  7. JAVA多线程详细讲解

    一个程序只有一个从头到尾的执行路径.这样做的优点是易于编程,无需考虑过多的情况.但是,由于单线程需要在上一个任务完成之后才开始下一个任务,所以其效率比较低.在真实的项目运行过程中都具有多任务同时执行的 ...

  8. 多线程进阶(五)--线程间的通信

    多线程基础概念:多线程入门(一) 多线程基础实现:多线程入门(二) 多线程管理:多线程基础(三) 线程间的状态转换:多线程基础(四) 本篇我们就简单的介绍下,线程间的通信: 多线程进阶(五)--线程间 ...

  9. 安琪拉教百里守约学并发编程之多线程基础

    <安琪拉与面试官二三事>系列文章 一个HashMap能跟面试官扯上半个小时 一个synchronized跟面试官扯了半个小时 <安琪拉教鲁班学算法>系列文章 安琪拉教鲁班学算法 ...

  10. Docker | Docker技术基础梳理(五) - Docker网络管理

    Docker | Docker技术基础梳理(五) - Docker网络管理 链接: 原文链接 原文链接: https://gitbook.cn/books/5b8f3c471966b44b00d265 ...

最新文章

  1. 一篇文章告诉你标准化和归一化的区别?
  2. oracle 数据不可恢复,Oracle数据恢复:错误叠加导致灾难不可恢复解决办法
  3. C语言用户标准是什么,C语言系统用户标准管理系统.doc
  4. 隐藏标准选择界面按钮
  5. Windows编程之定时器的使用和定时销毁桌面出现的窗口,以及窗口句柄的获取
  6. Android事件总线
  7. Oracle Enterprises Manager 12C安装
  8. mysql显示百分比例_显示值mysql的百分比
  9. Java基于JavaMail实现向QQ邮箱发送邮件遇到的问题
  10. 带着问题了解Openstack Neutron安全组
  11. 数字与字符串相关问题
  12. Security+ 学习笔记9 软件开发周期
  13. Nsight Compute Profile Kernel无法定位源码问题
  14. 初中英语和计算机融合的教学案例,信息技术与中学英语整合课教学案例
  15. 游戏开发入行大师攻略
  16. 三分钟看懂什么是运维
  17. flask爱家租房项目开发(十二)
  18. ls200_铁三角 LS200 双动铁入耳式耳机 个人客观听感(附IM02听感对比)
  19. 儿童学计算机编程好处,孩子学编程的好处和坏处
  20. Qt—设计颜色编辑选取对话框

热门文章

  1. jenkins集成自动化配置(二) 创建项目和项目配置
  2. xss.haozi.me靶机
  3. ie打开本地html页面慢,ie11 第一次浏览jquery+CSS3网页时候延时3秒
  4. 高中数学记录日志(2019人教A版必修二)
  5. Debian 7 安装vim
  6. 树洞程序php,微信公众平台开发(65) 微博树洞_PHP教程
  7. 六、Linux常用命令之压缩打包篇(gzip、gunzip、tar、zip、bzip2)
  8. windows无法格式化u盘怎么办_U盘提示格式化怎么办 U盘提示格式化解决方法【详解】...
  9. MacOs 查看本地IP和Mac地址
  10. coldfusion_ColdFusion组件-简介