解决线程安全问题的两种办法
package com.xt.java;/*** 创建3个窗口卖票,总票数为100张 使用实现Runnable接口的方式* 问题一:买票过程中,出现了重票、错票-->出现了线程安全问题* 问题出现的原因:当某个线程操作车票的过程中,尚未操作完成时,其它线程参与进来,也操作车票* 如何解决:当一个线程a在操作ticket时,其它线程不能参与进来。直到a操作完ticket后,其它线程才* 开始操作ticket。这种情况即使线程a出现了阻塞,也不能被改变。* 在Java中,我们通过同步机制,来解决线程的安全问题。* 方式一:同步代码块:* synchronized(同步监视器){* //需要被同步的代码* }* 说明:操作共享数据的代码,即为需要被同步的代码-->不能包括多了,也不能包括少了* 1.共享数据:多个线程共同操作的变量。比如:ticket* 2.同步监视器,俗称:锁。任何一个类的对象,都可以充当锁* 要求:多个线程必须共用同一把锁。* 补充:在实现Runnable接口创建多线程的方式中,我们可以考虑使用this来充当同步监视器* 方式二:同步方法:* 如果操作共享数据的代码完整地声明在一个方法中,我们不妨将这个方法声明为同步的。* 同步的方式:解决了线程安全问题----好处* 操作同步代码时,只能有一个线程参与,其他线程等待。相当于是一个单线程的过程,效率低。--局限性** @author tyl* @creat 2022-03-26-14:44*/
class Window1 implements Runnable{private int ticket=100;
// Object obj=new Object(); //注意位置@Overridepublic void run() {// Object obj=new Object(); //注意位置,放在此处,锁不唯一,故不安全while(true){//synchronized (obj){synchronized (this){ //此时的this:唯一的window1的对象if (ticket>0){try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName()+": 卖票,票号为:"+ticket);ticket--;}else{break;}}}}
}public class WindowTest1 {public static void main(String[] args) {Window1 w=new Window1();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();}
}
package com.xt.java;/*** @author tyl* @creat 2022-04-10-16:48** 例子,创建3个窗口卖票,总票数为100,使用继承Thread类的方式。* 使用同步代码块解决继承Thread类的方式的线程安全问题* 说明:在继承Thread创建多线程的方式中,慎用this充当同步监视器。考虑使用当前类充当同步监视器。**/
class Window2 extends Thread{private static int ticket=100;static Object obj=new Object(); //注意用static解决同一把锁的问题@Overridepublic void run() {while(true){//正确的//synchronized(obj){synchronized (Window2.class){ //Class clazz=Window2.class (类其实可以作为一个对象出现) Window2.class只会加载1次//synchronized(this){ //错误的,当前对象不唯一(继承方式)if (ticket>0){System.out.println(getName()+":卖票,票号为"+ticket);ticket--;}else{break;}}}}
}
public class WindowTest2{public static void main(String[] args) {Window2 w1=new Window2();Window2 w2=new Window2();Window2 w3=new Window2();w1.setName("窗口1");w2.setName("窗口2");w3.setName("窗口3");w1.start();w2.start();w3.start();}}
package com.xt.java;/*** @author tyl* @creat 2022-04-10-17:53** 使用同步方法解决实现Runnable接口的线程安全问题* 关于同步方法的总结:* 1.同步方法仍然涉及到同步监视器,只是不需要我们显式地声明。* 2.非静态的同步方法,同步监视器是this* 静态的同步方法,同步监视器是:当前类本身*/
class Window implements Runnable{private int ticket=100;@Overridepublic void run() {while(true){show();}}public synchronized void show(){ //同步监视器:thisif(ticket>0){System.out.println(Thread.currentThread().getName()+":卖票,票号为"+ticket);ticket--;}}
}
public class WindowTest3 {public static void main(String[] args) {Window w=new Window();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();}}
package com.xt.java;
/*** @author tyl* @creat 2022-04-10-18:09** 使用同步方法解决继承Thread类方式的线程安全问题*/
class Window4 extends Thread{private static int ticket=100;@Overridepublic void run() {while(true){show();}}private static synchronized void show(){ //同步监视器:Window4.class
// private synchronized void show(){ //同步监视器:w1、w2、w3 -->不唯一,故此种解决方式是错误的if (ticket>0){System.out.println(Thread.currentThread().getName()+":卖票,票号为"+ticket);ticket--;}}
}
public class WindowTest4{public static void main(String[] args) {Window4 w1=new Window4();Window4 w2=new Window4();Window4 w3=new Window4();w1.setName("窗口1");w2.setName("窗口2");w3.setName("窗口3");w1.start();w2.start();w3.start();}}
解决线程安全问题的两种办法相关推荐
- 如何解决线程安全问题?有几种方式?synchronized与lock有什么异同?
1.谈谈你对同步代码块中同步监视器和共享数据的理解以及各自要求? 同步监视器:俗称锁.①任何一个类的对象都可以充当:②多个线程共用同一把锁. 共享数据:多个线程共同操作的数据. 2.什么情况会产生线程 ...
- 小米手机html无法,小米手机无法开机进入不了桌面怎么解决 两种办法解决小米手机无法开机问题...
小米手机无法开机进入不了桌面怎么办,出现无法开机我们一个是可以刷机来解决,另一个临时办法就清除数据恢复出厂设置试一下,具体的两种解决无法开机问题,下面小编都为各位介绍 注意:不管是什么原因导致你手机无 ...
- 4种解决线程安全问题的方式
前言 线程安全问题,在做高并发的系统的时候,是程序员经常需要考虑的地方.怎么有效的防止线程安全问题,保证数据的准确性?怎么合理的最大化的利用系统资源等,这些问题都需要充分的理解并运行线程.当然关于多线 ...
- 小米5进系统无显示无服务器,小米手机无法开机进入不了桌面怎么解决 两种办法解决小米手机无法开机问题...
注意:不管是什么原因导致你手机无法开机我们都可以参考下面的方法来解决了,具体的如下. 方法一:小米手机无法进入系统的常用方法 1 既然不能开机了那肯定是已经关机了,我们现在只要同时按下开机键和音量放大 ...
- 线程安全问题的 3 种解决方案!
作者 | 磊哥 来源 | Java面试真题解析(ID:aimianshi666) 转载请联系授权(微信ID:GG_Stone) 线程安全是指某个方法或某段代码,在多线程中能够正确的执行,不会出现数据不 ...
- 如何解决线程安全问题
如何解决线程安全问题 怎么解决线程的安全问题呢? 基本上所有解决线程安全问题的方式都是采用"序列化临界资源访问"的方式,即在同一时刻只有一个线程操作临界资源,操作完了才能让其他线程 ...
- Java解决线程安全问题
文章目录 背景 1. 线程安全问题 1.1 什么是线程安全? 1.2 产生的原因 1.3 实例(买票超卖问题) 1.4 如何确定是否存在线程安全问题? 2. 如何解决线程安全问题? 2.1 不可变(I ...
- 多线程的创建方式和解决线程安全问题
一 基本概念 ①程序(program)是为完成特定任务.用某种语言编写的一组指令的集合.即指一 段静态的代码,静态对象. ②进程(process)是程序的一次执行过程,或是正在运行的一个程序.是一个 ...
- eclipse new server Cannot create a server using the selected type 网上有两种办法,其实原理一样...
eclipse new server Cannot create a server using the selected type 网上有两种办法,其实原理一样 第一种说法: 还真的找到解决的方法了, ...
最新文章
- Java多线程--synchronized修饰普通方法和修饰静态方法的区别
- libnss mysql_Ubuntu通过LDAP集成AD域账号登录(libnss-ldap方式)
- 【转】(五)unity4.6Ugui中文教程文档-------概要-UGUI Interaction Components
- 新购阿里云服务器ECS创建之后无法ssh连接的问题处理
- AVS游程解码、反扫描、反量化和反变换优化设计
- wxpython是干嘛的_你都用 Python 来做什么?
- E: Sub-process /usr/bin/dpkg returned an error code (1)解决办法
- php _call call_user_func_array,PHP call_user_func和call_user_func_array函数的简单理解与应用分析...
- Android 系统(80)---Android 8.0 7.0 6.0 动态权限管理
- 研究员告警:严重漏洞影响数千万台IoT设备,可远程查看实时音视频并接管设备...
- 让服务器自动从HG版本库中下载代码
- 宅男福利:Python爬取某站所有漫画(赶紧收藏)
- Geeks 面试题:Fibonacci numbers 优化为lgn效率
- 浅析硬件构造Tone mapping曲线
- 51单片机系列--蜂鸣器
- 判断无向图G是否是一颗树
- Matlab时频工具箱tftb-0.2安装
- Android仿新浪微博弹出界面动画,Android仿新浪微博启动界面或登陆界面(1)
- mongodb查询后排序
- 利用RSA非对称加密对文本信息进行加密