[Java基础] 线程

​写在前面

在写程序的时候,遇到没有关联的两段代码(一个函数的执行不需等待另一个函数的返回值),怎么能让他们同时进行呢?让我们进入线程的世界寻找答案。

活动地址:CSDN21天学习挑战赛

学习的最大理由是想摆脱平庸,早一天就多一份人生的精彩;迟一天就多一天平庸的困扰。各位小伙伴,如果您:
想系统/深入学习某技术知识点…
一个人摸索学习很难坚持,想组团高效学习…
想写博客但无从下手,急需写作干货注入能量…
热爱写作,愿意让自己成为更好的人…

什么是线程?

线程(thread)是一个程序内部的一条执行路径。

我们之前启动程序执行后,main方法的执行其实就是一条单独的执行路径。

public static void main(String[] args) {    

        // 代码…    

        for (int i = 0; i < 10; i++) {        

                System.out.println(i);    

        }    

        // 代码...

}

 程序中如果只有一条执行路径,那么这个程序就是单线程的程序。

多线程是什么?

多线程是指从软硬件上实现多条执行流程的技术。

 关于多线程需要学会什么?

 多线程的创建

方式一:继承Thread类

方式二:实现Runnable接口

方式三:JDK 5.0新增:实现Callable接口

 Thread类

Java是通过java.lang.Thread 类来代表线程的。 按照面向对象的思想,Thread类应该提供了实现多线程的方式。

多线程的实现方案一:继承Thread类

定义一个子类MyThread继承线程类java.lang.Thread,重写run()方法

创建MyThread类的对象

调用线程对象的start()方法启动线程(启动后还是执行run方法的)

优点:编码简单

缺点:线程类已经继承Thread,无法继承其他类,不利于扩展。

1、为什么不直接调用了run方法,而是调用start启动线程。

直接调用run方法会当成普通方法执行,此时相当于还是单线程执行。

只有调用start方法才是启动一个新的线程执行。

2、把主线程任务放在子线程之前了。

这样主线程一直是先跑完的,相当于是一个单线程的效果了。

 多线程的实现方案二:实现Runnable接口

定义一个线程任务类MyRunnable实现Runnable接口,重写run()方法

创建MyRunnable任务对象

把MyRunnable任务对象交给Thread处理。

调用线程对象的start()方法启动线程

优点:线程任务类只是实现接口,可以继续继承类和实现接口,扩展性强。

缺点:编程多一层对象包装,如果线程有执行结果是不可以直接返回的。 

实现Runnable接口(匿名内部类形式)

可以创建Runnable的匿名内部类对象。

交给Thread处理。

调用线程对象的start()启动线程。

多线程的实现方案三:利用Callable、FutureTask接口实现。

得到任务对象

        定义类实现Callable接口,重写call方法,封装要做的事情。

        用FutureTask把Callable对象封装成线程任务对象。

把线程任务对象交给Thread处理。

调用Thread的start方法启动线程,执行任务

线程执行完毕后、通过FutureTask的get方法去获取任务执行的结果。 

优点:

线程任务类只是实现接口,可以继续继承类和实现接口,扩展性强。

可以在线程执行完毕后去获取线程执行的结果。

缺点:编码复杂一点。 

 Thread常用API说明

Thread常用方法:获取线程名称getName()、设置名称setName()、获取当前线程对象currentThread()。

至于Thread类提供的诸如:yield、join、interrupt、不推荐的方法 stop 、守护线程、线程优先级等线程的控制方法,在开发中很少使用,这些方法会在高级篇以及后续需要用到的时候再为大家讲解。

 

线程安全问题

多个线程同时操作同一个共享资源的时候可能会出现业务安全问题,称为线程安全问题。

取钱模型演示

需求:小明和小红是一对夫妻,他们有一个共同的账户,余额是10万元。

如果小明和小红同时来取钱,而且2人都要取钱10万元,可能出现什么问题呢?

 

线程同步的核心思想

加锁,把共享资源进行上锁,每次只能一个线程进入访问完毕以后解锁,然后其他线程才能进来。

 

同步代码块

作用:把出现线程安全问题的核心代码给上锁。

原理:每次只能一个线程进入,执行完毕后自动解锁,其他线程才可以进来执行。

 

锁对象要求

理论上:锁对象只要对于当前同时执行的线程来说是同一个对象即可。 

锁对象用任意唯一的对象好不好呢?

不好,会影响其他无关线程的执行。 

锁对象的规范要求

规范上:建议使用共享资源作为锁对象。

对于实例方法建议使用this作为锁对象。

对于静态方法建议使用字节码(类名.class)对象作为锁对象。

同步方法

作用:把出现线程安全问题的核心方法给上锁。

原理:每次只能一个线程进入,执行完毕以后自动解锁,其他线程才可以进来执行。 

格式

同步方法底层原理

同步方法其实底层也是有隐式锁对象的,只是锁的范围是整个方法代码。

如果方法是实例方法:同步方法默认用this作为的锁对象。

但是代码要高度面向对象! 如果方法是静态方法:同步方法默认用类名.class作为的锁对象。 

Lock锁

为了更清晰的表达如何加锁和释放锁,JDK5以后提供了一个新的锁对象Lock,更加灵活、方便。

Lock实现提供比使用synchronized方法和语句可以获得更广泛的锁定操作。

Lock是接口不能直接实例化,这里采用它的实现类ReentrantLock来构建Lock锁对象

public ReentrantLock​()

获得Lock锁的实现类对象

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

鲸海鹿林

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值