Java学习之多线程(线程安全问题及线程同步)
一、线程安全问题产生前提:
1、多线程操作共享数据
2、线程任务中有多条代码
class Ticket implements Runnable
{
//2.共享数据
private int num = 100; public void run()
{
while(true)
{
//3.多条代码
if(num > 0)
{
try{Thread.sleep(10);}catch(InterruptedException e){}
System.out.println(Thread.currentThread().getName()+"==="+num--);
}
}
}
} class TicketDemo
{
public static void main(String[] args)
{
Ticket t = new Ticket();
//1.多线程操作同一个对象
Thread t1 =new Thread(t);
Thread t2 =new Thread(t);
Thread t3 =new Thread(t);
Thread t4 =new Thread(t); t1.start();
t2.start();
t3.start();
t4.start();
}
}
运行结果:
出现线程安全问题了
二、解决线程安全问题
解决线程安全问题的两种方式:
①、同步代码块
格式:
synchronized(对象)
{
//需要被同步的代码;
... ...
}
解决上面线程安全问题的代码:
class Ticket implements Runnable
{
//2.共享数据
private int num = 100;
//同步锁:对象
private Object o=new Object();
public void run()
{
while(true)
{
synchronized(o)
{
//3.多条代码
if(num > 0)
{
try{Thread.sleep(10);}catch(InterruptedException e){}
System.out.println(Thread.currentThread().getName()+"==="+num--);
}
}
}
}
}
结果:
解决原理:多线程在使用同步代码块时,使用了同一个同步锁(Object的对象)
②、同步函数
格式:
public synchronized 方法返回值类型 方法名(参数列表)
{
... ...
}
2.1、非静态同步函数
代码:
class Ticket implements Runnable
{
//2.共享数据
private int num = 100;
//同步锁:对象
//private Object o=new Object();
public void run()
{
while(true)
{
/*
synchronized(o)
{
//3.多条代码
if(num > 0)
{
try{Thread.sleep(10);}catch(InterruptedException e){}
System.out.println(Thread.currentThread().getName()+"==="+num--);
}
}
*/
show();
}
}
public synchronized void show()
{
//3.多条代码
if(num > 0)
{
try{Thread.sleep(10);}catch(InterruptedException e){}
System.out.println(Thread.currentThread().getName()+"==="+num--);
}
}
}
结果:
2.2、静态同步函数
代码:
class Ticket implements Runnable
{
//2.共享数据
private static int num = 100;
//同步锁:对象
//private Object o=new Object();
public void run()
{
while(true)
{
/*
synchronized(o)
{
//3.多条代码
if(num > 0)
{
try{Thread.sleep(10);}catch(InterruptedException e){}
System.out.println(Thread.currentThread().getName()+"==="+num--);
}
}
*/
show();
}
}
public static synchronized void show()
{
//3.多条代码
if(num > 0)
{
try{Thread.sleep(10);}catch(InterruptedException e){}
System.out.println(Thread.currentThread().getName()+"==="+num--);
}
}
}
结果:
同步的弊端:效率低,因为同步外的线程都会判断同步锁
Java学习之多线程(线程安全问题及线程同步)的更多相关文章
- Java学习笔记-多线程-创建线程的方式
创建线程 创建线程的方式: 继承java.lang.Thread 实现java.lang.Runnable接口 所有的线程对象都是Thead及其子类的实例 每个线程完成一定的任务,其实就是一段顺序执行 ...
- 0037 Java学习笔记-多线程-同步代码块、同步方法、同步锁
什么是同步 在上一篇0036 Java学习笔记-多线程-创建线程的三种方式示例代码中,实现Runnable创建多条线程,输出中的结果中会有错误,比如一张票卖了两次,有的票没卖的情况,因为线程对象被多条 ...
- 2019/3/7 Java学习之多线程(基础)
Java学习之多线程 讲到线程,就必须要懂得进程,进程是相当于一个程序的开始到结束,而线程是依赖于进程的,没有进程,就没有线程.线程也分主线程和子线程,当在主线程开启子线程时,主线程结束,而子线程还可 ...
- java学习笔记 --- 多线程(线程安全问题——同步代码块)
1.导致出现安全问题的原因: A:是否是多线程环境 B:是否有共享数据 C:是否有多条语句操作共享数据 2.解决线程安全问题方法: 同步代码块: synchronized(对象){ 需要同步的代码; ...
- 0041 Java学习笔记-多线程-线程池、ForkJoinPool、ThreadLocal
什么是线程池 创建线程,因为涉及到跟操作系统交互,比较耗费资源.如果要创建大量的线程,而每个线程的生存期又很短,这时候就应该使用线程池了,就像数据库的连接池一样,预先开启一定数量的线程,有任务了就将任 ...
- 0040 Java学习笔记-多线程-线程run()方法中的异常
run()与异常 不管是Threade还是Runnable的run()方法都没有定义抛出异常,也就是说一条线程内部发生的checked异常,必须也只能在内部用try-catch处理掉,不能往外抛,因为 ...
- 0039 Java学习笔记-多线程-线程控制、线程组
join线程 假如A线程要B线程去完成一项任务,在B线程完成返回之前,不进行下一步执行,那么就可以调用B线程的join()方法 join()方法的重载: join():等待不限时间 join(long ...
- 0038 Java学习笔记-多线程-传统线程间通信、Condition、阻塞队列、《疯狂Java讲义 第三版》进程间通信示例代码存在的一个问题
调用同步锁的wait().notify().notifyAll()进行线程通信 看这个经典的存取款问题,要求两个线程存款,两个线程取款,账户里有余额的时候只能取款,没余额的时候只能存款,存取款金额相同 ...
- 0036 Java学习笔记-多线程-创建线程的三种方式
创建线程 创建线程的三种方式: 继承java.lang.Thread 实现java.lang.Runnable接口 实现java.util.concurrent.Callable接口 所有的线程对象都 ...
随机推荐
- 《JAVA设计模式》之代理模式(Proxy)
在阎宏博士的<JAVA与模式>一书中开头是这样描述代理(Proxy)模式的: 代理模式是对象的结构模式.代理模式给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用. 代理模式的结 ...
- Go语言格式化字符串
%s: 普通字符串 %q: 引号包含字符串 %x, %o, %b: 十六进制,8进制,2进制 %t: bool值 %d decimal integer %v any value in a natura ...
- [Linux] 013 其他文件搜索命令
1. 文件搜索命令:locate 命令名称:locate 命令所在路径:/bin/locate 执行权限:所有用户 语法:locate 文件名 功能描述:在文件资料库中查找文件 范例: $ locat ...
- [Bzoj1047][HAOI2007]理想的正方形(ST表)
题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=1047 题目虽然有一个n的限制,但求二维区间最值首先想到的还是RMQ,但是如果按照往常RM ...
- python print (x,end = '') 意思作用
for x in range(10) python print(x)换行输出 for x in range(10) python print (x,end = '') 不换行输出
- opencv视频流的读取和处理
Opencv提供一个简单易用的框架以提取视频文件和USB摄像头中的图像帧,如果只是想读取某个视频,你只需要创建一个VideoCapture实例,然后在循环中提取每一帧.下面是一个简单的代码 #incl ...
- Dubbo源码学习总结系列一 总体认识
本文写作时,dubbo最高版本是V2.6.0. 写这篇文章主要想回答以下4个问题: 一.dubbo是什么?完成了哪些主要需求? 二.dubbo适用于什么场景? 三.dubbo的总体架构是什么样的? ...
- 将ibatis迁移到mybatis3的过程记录
将ibatis迁移到mybatis3的过程记录 场景:有些以前的老项目是使用ibatis开发的,现在有转换成mybatis3的需求. 环境准备:需要安装Ant,以下是本人的安装版本,具体怎么安装不再赘 ...
- 13-H.264编码解码器的无线应用:1080P60 3D无线影音传输器
H.264编码解码器的无线应用:1080P60 3D无线影音传输器 一.应用领域 家庭媒体娱乐中心 新闻现场采访 无线3D投影机 高清视频会议终端无线延长器 教学,医疗示教 考古,高档商业区域,监狱等 ...
- Linux学习笔记之目录配置
一.目录配置 相关目录说明 /bin 二进制文件 /boot 系统启动文件(内核的初始化文件等) /dev 设备文件(硬盘等) /e ...