 同步锁机制:
在《Thinking in Java》中,是这么说的:对于并发工作,你需要某种方式来防
止两个任务访问相同的资源(其实就是共享资源竞争)。 防止这种冲突的方法
就是当资源被一个任务使用时,在其上加锁。第一个访问某项资源的任务必须
锁定这项资源,使其他任务在其被解锁之前,就无法访问它了,而在其被解锁
之时,另一个任务就可以锁定并使用它了。
 synchronized 的锁是什么 ?
任意对象都可以作为同步锁。所有对象都自动含有单一的锁(监视器)。
同步方法的锁:静态方法(类名.class)、非静态方法(this)
同步代码块:自己指定,很多时候也是指定为this或类名.class
注意:
必须确保使用同一个资源的 多个线程共用一把锁,这个非常重要,否则就
无法保证共享资源的安全
一个线程类中的所有静态方法共用同一把锁(类名.class),所有非静态方
法共用同一把锁(this),同步代码块(指定需谨慎)

使用同步代码块解决继承Thread类的方式的线程安全问题
package com.atguigu.java;

/**
* 使用同步代码块解决继承Thread类的方式的线程安全问题
*
* 例子:创建三个窗口卖票,总票数为100张.使用继承Thread类的方式
*
* 说明:在继承Thread类创建多线程的方式中,慎用this充当同步监视器,考虑使用当前类充当同步监视器。
*
* @author ch
* @create 2021-02-13 下午 4:20
*/
class Window2 extends Thread{ private static int ticket = 100; private static Object obj = new Object(); @Override
public void run() { while(true){
//正确的
// synchronized (obj){
synchronized (Window2.class){//Class clazz = Window2.class,Window2.class只会加载一次
//错误的方式:this代表着t1,t2,t3三个对象
// synchronized (this){ if(ticket > 0){ try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
} System.out.println(getName() + ":卖票,票号为:" + ticket);
ticket--;
}else{
break;
}
} } }
} public class WindowTest2 {
public static void main(String[] args) {
Window2 t1 = new Window2();
Window2 t2 = new Window2();
Window2 t3 = new Window2(); t1.setName("窗口1");
t2.setName("窗口2");
t3.setName("窗口3"); t1.start();
t2.start();
t3.start(); }
}
使用同步方法解决实现Runnable接口的线程安全问题

package com.atguigu.java;

/**
* 使用同步方法解决实现Runnable接口的线程安全问题
*
*
* 关于同步方法的总结:
* 1. 同步方法仍然涉及到同步监视器,只是不需要我们显式的声明。
* 2. 非静态的同步方法,同步监视器是:this
* 静态的同步方法,同步监视器是:当前类本身
*
* @author ch
* @create 2021-02-15 上午 11:35
*/ class Window3 implements Runnable { private int ticket = 100; @Override
public void run() {
while (true) { show();
}
} private synchronized void show(){//同步监视器:this
//synchronized (this){ if (ticket > 0) { try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
} System.out.println(Thread.currentThread().getName() + ":卖票,票号为:" + ticket); ticket--;
}
//}
}
} public class WindowTest3 {
public static void main(String[] args) {
Window3 w = new Window3(); Thread t1 = new Thread(w);
Thread t2 = new Thread(w);
Thread t3 = new Thread(w); t1.setName("窗口1");
t2.setName("窗口2");
t3.setName("窗口3"); t1.start();
t2.start();
t3.start();
} }

使用同步方法处理继承Thread类的方式中的线程安全问题

package com.atguigu.java;

/**
* 使用同步方法处理继承Thread类的方式中的线程安全问题
*
* @author ch
* @create 2021-02-15 上午 11:43
*/
class Window4 extends Thread { private static int ticket = 100; @Override
public void run() { while (true) { show();
} }
private static synchronized void show(){//同步监视器:Window4.class
//private synchronized void show(){ //同步监视器:t1,t2,t3。此种解决方式是错误的
if (ticket > 0) { try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
} System.out.println(Thread.currentThread().getName() + ":卖票,票号为:" + ticket);
ticket--;
}
}
} public class WindowTest4 {
public static void main(String[] args) {
Window4 t1 = new Window4();
Window4 t2 = new Window4();
Window4 t3 = new Window4(); t1.setName("窗口1");
t2.setName("窗口2");
t3.setName("窗口3"); t1.start();
t2.start();
t3.start(); }
}
使用同步方法解决实现Runnable接口的线程安全问题
/**
* 使用同步方法解决实现Runnable接口的线程安全问题
*
*
* 关于同步方法的总结:
* 1. 同步方法仍然涉及到同步监视器,只是不需要我们显式的声明。
* 2. 非静态的同步方法,同步监视器是:this
* 静态的同步方法,同步监视器是:当前类本身
*
* @author CH
* @create 2021-02-15 上午 11:35
*/ class Window3 implements Runnable { private int ticket = 100; @Override
public void run() {
while (true) { show();
}
} private synchronized void show(){//同步监视器:this
//synchronized (this){ if (ticket > 0) { try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
} System.out.println(Thread.currentThread().getName() + ":卖票,票号为:" + ticket); ticket--;
}
//}
}
} public class WindowTest3 {
public static void main(String[] args) {
Window3 w = new Window3(); Thread t1 = new Thread(w);
Thread t2 = new Thread(w);
Thread t3 = new Thread(w); t1.setName("窗口1");
t2.setName("窗口2");
t3.setName("窗口3"); t1.start();
t2.start();
t3.start();
} }



 

Synchronized的各场景使用方法(多窗口售票例子接上篇)的更多相关文章

  1. Selenium_使用switch_to.window方法处理窗口切换(12)

    想一下这样的场景,打开页面A点击一个链接,在一个新的窗口打开页面B,由于之前的driver实例对象在页面A,但是你接下来操作的元素在页面B中,此时脚本就会报错找不到元素.该场景需要使用到seleniu ...

  2. 从普通函数到对象方法 ------Windows窗口过程的面向对象封装

    原文地址:http://blog.csdn.net/linzhengqun/article/details/1451088 从普通函数到对象方法 ------Windows窗口过程的面向对象封装 开始 ...

  3. Java基础 继承的方式创建多线程 / 线程模拟模拟火车站开启三个窗口售票

    继承的方式创建多线程 笔记: /**继承的方式创建多线程 * 线程的创建方法: * 1.创建一个继承于Thread 的子类 * 2.重写Thread类的run()方法 ,方法内实现此子线程 要完成的功 ...

  4. 第15.35节 PyQt编程实战:结合QDial实现的QStackedWidget堆叠窗口程序例子

    老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 一.案例说明 本案例是老猿在学习QStackedWidget中的一个测试案例,该案例使用QStack ...

  5. extern外部方法使用C#简单例子

    外部方法使用C#简单例子 1.增加引用using System.Runtime.InteropServices; 2.声明和实现的连接[DllImport("kernel32", ...

  6. Python中使用item()方法遍历字典的例子

    Python中使用item()方法遍历字典的例子 这篇文章主要介绍了Python中使用item()方法遍历字典的例子,for...in这种是Python中最常用的遍历字典的方法了,需要的朋友可以参考下 ...

  7. synchronized各种使用场景

    synchronized属于JVM锁机制 一.使用场景 在并发量比较小的情况下访问公共资源,使用synchronized是个不错的选择,但是在并发量比较高的情况下,其性能下降很严重 二.应用场景:同步 ...

  8. 【并发编程】synchronized的使用场景和原理简介

    1. synchronized使用 1.1 synchronized介绍 在多线程并发编程中synchronized一直是元老级角色,很多人都会称呼它为重量级锁.但是,随着Java SE 1.6对sy ...

  9. Unity3D 4.61 实现淡入淡出的场景过渡方法。

    还在学习过程中,如果有大大看到请指点. orz原来官方就有了更好的处理方法的教程,具体查看下面视屏. [Unity官方实例教程 秘密行动] Unity官方教程<秘密行动>(五) 屏幕渐变效 ...

  10. [Unity-24] Unity的四种载入场景的方法

    Unity官方提供了4种载入场景(scene)的方法.各自是: 1. Application.LoadLevel():同步载入 2. Application.LoadLevelAsync():异步载入 ...

随机推荐

  1. 题解:CF1551D1 Domino (easy version)

    题解:CF1551D1 Domino (easy version) 分析 题目中保证 \(n\times m\) 为偶数,下面进行分类讨论. 情况一 如果 \(n\) 和 \(m\) 都是偶数,那么可 ...

  2. 参与 2024 第四季度官方 Flutter 开发者调查

    Flutter 3.24 和 Dart 3.5 稳定版发布 已有三月之久,今年最后一次开发者调查也如约而至! 自 Flutter 3.24 正式发布以来,团队通过一系列补丁更新不断优化平台稳定性和开发 ...

  3. require/import路径中的叹号是什么?

    问题: 之前在一些开源项目的源码里,以及一些文章里,见到如下这样的require/import路径,其中包含形如!.的片段,不知道是什么意思: // https://juejin.im/post/68 ...

  4. Personal Wiki

    What is a PersonalWiki? It's like WardsWiki, but it's yours. It can be: a free-form database a Perso ...

  5. Avalonia UI 中 Styles 与 ControlTheme 的区别

    目录 目录 介绍 使用方式 全局主题 (Global Theme) 局部主题 (Local Theme) 控件主题 (ControlTheme) 问题描述 问题分析 问题1 区别 问题2 重写Temp ...

  6. PythonDay5Advance

    PythonDay5Advance 函数和模块 main函数要有,用户自己选择要做的功能,根据选择调用不同的函数 用户注册的信息需要使用一个文件存储,登录需要判断用户是否存在,密码是否正确 注册的时候 ...

  7. Qt QLabel 文字自适应大小

    直接上代码: void Adjust(QLabel * lb) { QFont font(lb->font()); while(1) { QFontMetrics fontMetrics(fon ...

  8. 【Amadeus原创】docker安装TOMCAT,并运行本地代码

    1,docker 下载tomcat [root@it-1c2d ~]# docker pull tomcat ... [root@it-1c2d ~]# docker images REPOSITOR ...

  9. 【Amadeus原创】域密码到期发送提醒邮件的超简单方法

    1,AD服务器下载安装免费的卓豪AD管理工具 https://www.manageengine.cn/products/self-service-password/free-password-expi ...

  10. spring boot 启动原理解析

    https://www.cnblogs.com/xiaoxi/p/7999885.html 我们开发任何一个Spring Boot项目,都会用到如下的启动类 1 @SpringBootApplicat ...