Java多线程案例及其代码实现

本文深入探讨Java多线程的实战案例,包括单例模式(饿汉与懒汉模式)、阻塞队列、定时器和线程池的实现与原理。讲解了线程安全、阻塞效果、任务调度和线程复用的重要性,并通过代码示例展示了如何在Java中创建和管理这些多线程结构。
摘要由CSDN通过智能技术生成

目录

案例一:单例模式

1.饿汉模式的代码实现

2.懒汉模式

案例二:阻塞队列

1.线程安全

2.产生阻塞效果

        1.如果队列为空,尝试出队列,就会出现阻塞现象,阻塞到队列不为空为止。

        2.如果队列未满,尝试入队列,也会出现阻塞,阻塞到队列不为满为止。

案例三:定时器

1.描述任务

2.组织任务(使用一定的数据结构把这些任务给放到一起)

 3.执行时间到了的任务

案例四:线程池


案例一:单例模式

线程安全的单例模式有两种典型实现:

1.饿汉模式。

2.懒汉模式。

什么是饿汉模式什么是懒汉模式呢,打个比方来说,饿汉模式就像我们有四个碗,每次用完四个碗,就洗干净,懒汉呢就是我吃完后这四个碗我不喜欢,需要的时候呢,要几个我在去洗几个(但这样反而是更加高效的)

总结:

饿汉模式的单例模式:直接去创建实例。

懒汉模式的单例模式:是不太着急的去创建实例,只有在用的时候,才真正创建。

1.饿汉模式的代码实现

在类中,我们直接使用static 创建一个势力,并且立即进行还是实例化,因为实现的是单例模式,所以将他的构造方法设为private,防止我们在其他地方不小心new这个Singleton,这样,这个instance就是Singleton的唯一实例 ,创建一个方法,让外界可以拿到这个唯一的实例。那么这个是线程安全的吗? 当然是,因为饿汉模式中的getInstance,仅仅只是读取变量内容,如果多个线程只是读同一个内容,不进行修改,此时,线程任然是安全的。

2.懒汉模式

 

 同饿汉模式不同的是,并不是一开始就创建出实例,只有当外界真正使用到getInstance的时候进入判断,如果这个实例不存在的话才会创建,但这个还是存在问题的,我们发现,这个和饿汉模式不同的是他的getInstance方法不仅仅进行了读操作,还包含了修改操作,不是原子性的,所以,存在着线程安全问题,就像我们之前讲到的,两个线程对一个变量进行增值,这里就有可能会创建出多个实例。那么如何保证懒汉模式的线程安全呢?这里我们就想到了加锁

 虽然现在我们加锁了,但是还是存在问题,出现线程安全是因为没有初始化,多个线程读写操作一起,可能会创建很多事例,但是当我们已经将instance初始化之后,这个方法就只剩下了读操作,此时是线程安全的,那么这样加锁的话,无论代码是初始化之后还是之前,调用getInstance都会进行加锁,这样就可能会产生所得竞争,但是这样的竞争其实是没有必要的,这样只会降低程序的运行速度,所以,我们就要对他进行优化

 只有当instance没有创建实例的时候才会给它加锁,当他已经初始化了,我们就只需要读即可。我们发现内外两个判定条件一模一样,但是他们的作用却大不相同,外面的条件判定,是在判断是不是要加锁,内层的是判断是否要创建实例,只是刚好这两个目的就是判断instance是否为null。经过一顿整改,结果还有一个问题,就是内存可见性问题,当我们如果多个线程,都去调用这里的getInstance,就会造成大量的读操作,然后编译期就会自己优化,把合格读内存操作优化成读寄存器操作,当触发这个优化后,后续如果已经完成了对instance的修改,那么后面的线程感知不到,有人会想,不是加了synchronized吗?是的,这个内存可见性问题,可能会引起第一个if判定失效,但是对于第二个并没有多大影响,因此只是引起了第一层的误判,也及时导致不该加锁的加锁。解决的方法只需要给instance加上volatile即可。

 这样,完全体的线程安全单例模式的懒汉模式就完成了。

总结一下:我们写饿汉模式就是直接创建实例,懒汉模式呢,使用在创建,懒汉模式要注意三点:1.正确的加锁位置

2.双重if判定

3.内存可视化问题

案例二:阻塞队列

既然是队列,那就同样也是先进先出,相比于普通队列,阻塞队列又有一些其他方面的功能。

1.线程安全

2.产生阻塞效果

        1.如果队列为空,尝试出队列,就会出现阻塞现象,阻塞到队列不为空为止。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值