JavaSE笔记-------第八章 多线程

.基本概念:程序、进程、线程
在这里插入图片描述

多线程的优点: 1.提高应用程序的相应 2.提高计算机系统CPU的利用率 3.改善程序结构
创建多线程方式一:继承Thread类
1.创建一个继承于Thread类的子类
2.重写Thread类的run()方法---->将此线程执行的操作声明在run()中
3.创建Thread类的子类的对象
4.通过此对象调用start()方法
作用:①启动当前线程 ②调用当前线程的run()犯法
问题一:我们不能通过直接调用run()的方法启动线程
问题二:不可以使用已经start()的线程再启动一个线程
Thread类中的常用方法:
1.start():启动当前线程,调用当前线程的run()
2.run():通常需要重写Thread类中的此方法,将创建的线程需要执行的操作声明在此方法中。
3.currentThread():静态方法,返回当前执行代码的线程
4.getName():获取当前线程的名字
5.setName():设置当前线程的名字
6.yield():释放当前CPU的执行权
7.join():在线程a中调用线程b的join(),此时线程a就进入阻塞状态,知道线程b完全执行完以后,才执行线程a
8.stop():已过时。 当执行完此方法时,强制结束此线程
9.sleep(long millitime):让当前线程睡眠指定的毫秒数,阻塞状态
10.isAlive():判断当前线程是否还存活
线程优先级:
1.MAX_PRIORITY:10
MIN_PRIORITY:1
NORM_PRIORITY:5
2.getPriority()获取优先级
setPriority():设置优先级
说明:高优先级的线程要抢占低优先级线程CPU的执行权,但是只是从概率上讲,不是一定高优先级先执行。
创建多线程的方式2:继承Runnable接口
1.创建一个实现Runnable接口的类
2.实现类去实现Runnable接口的抽象方法run()
3.创建实现类的对象
4.将此对象作为参数传递到Thread类的构造器中,创建Thread类的对象
5.通过Thread类的对象调用start()
比较创建线程的两种方式:
开发中优先选择实现Runnable接口的方式。
原因:1.实现的方式没有类的单继承性的局限性
2.实现的方式更适合来处理多个线程有共享数据的情况
联系:Thread类实现了Runnable接口
相同点:两种方式都要重写run()方法,将要执行的逻辑写到run()中
线程的生命周期:Thread.State类中
新建、就绪、运行、阻塞、死亡
在这里插入图片描述

线程的安全问题:
提出:多个线程执行的不确定性引起执行结果的不稳定
多个线程对账本的共享,会造成操作的不完整性,会破坏数据
解决:当一个线程在操作共享数据时,其他线程不能参与进来,直到操作完其他线程才能操作,这种情况下即使线程a出现了阻塞,也不能被改变
在Java中,通过同步机制来解决线程的安全问题
方式一:同步代码块
synchronized(同步监视器){
//需要被同步的代码
}
说明:1.操作共享数据的代码即为需要被同步的代码—>不能包含代码多了也不能少了
2.共享数据:多个线程共同操作的变量
3.同步监视器:俗称:锁 任何一个类的对象都能充当锁
要求:多个线程必须要使用同一把锁
补充:在实现Runnable接口创建多线程的方式中,我们可以考虑使用this充当同步监视器。在用继承Thread类的方式中,可以考虑使用类名.class充当同步监视器
方式二:同步方法
如果操作共享数据的代码完成的声明在一个方法中,可将此方法声明成同步方法
1.同步方法仍然涉及到同步监视器,只是不需要我们显式的声明
2.非静态的同步方法,同步监视器是this
静态的同步方法,同步监视器是当前类.class
同步的方式解决了多线程的安全问题–>好处
操作同步代码时,只能有一个线程参与,其他线程等待,相当于是一个单线程的过程,效率低—>坏处
死锁问题:
1.理解:不同的线程分别占用对方需要的同步资源不放弃,都在等待对方放弃自己需要的同步资源,就形成了死锁
2.说明:
1.出现死锁后,不会出现异常,也不会出现提示,只是所有的线程都处于阻塞状态,无法继续
2.我们使用同步时,应避免死锁

解决线程安全问题的方式三:Lock锁—>JDK5.0新增
1.实例化ReentrantLock
以下声明在try-finally里
2.调用lock()方法
3.调用解锁方法 unlock()
面试题:synchronized与lock的一同
同:二者都可以用来解决线程的安全问题
异:synchronized机制在执行完相应的同步代码后自动释放同步监视器
Lock需要手动的启动同步(lock()),同时结束同步也需要手动的实现(unlock())
优先使用顺序;Lock–>同步代码块—>同步方法
线程的通信
涉及到的方法:
wait():一旦执行此方法,当前线程就进入到阻塞状态,并释放同步监视器
notify():一旦执行此方法,就会唤醒被wait的一个线程,如果有多个线程wait,唤醒优先级高的
notifyAll():唤醒所有wait方法
说明:
1.wait()、notify()、notifyAll()三个方法必须使用在同步代码块或同步方法中
2.wait()、notify()、notifyAll()三个方法调用者必须是同步方法或同步代码块的同步监视器,否则报错
3.定义在Object类中
面试题:sleep()和wait()异同
相同点:一旦执行方法,都可以使当前线程进入阻塞状态
不同点:1.两个方法声明的位置不同:Thread类中声明sleep() Object类中声明wait()
2.调用的要求不同:sleep()可以在任何需要的场景下使用;wait()必须使用在同步方法或者同步代码块中
3.sleep()不会释放同步监视器,wait()会释放
JDK5.0新增线程创健方式:
1.实现Callable接口
①创健一个实现Callable接口的实现类
②实现call方法,将此线程需要执行的操作声明在call方法中
③创健Callable接口实现类的对象
④创健FutureTask对象
⑤创健Thread类对象
⑥获取Callable中的call()方法的返回值:get()
如何理解实现Callable接口的方式创健多线程比Runnable更强大?
1.call()方法可以有返回值
2.call()可以抛出异常获取异常信息
3.Callable支持泛型
2.使用线程池 Executors
好处:提高响应速度、降低资源消耗、便于线程管理
①提供指定线程数量的线程池
②执行指定的线程的操作 execute() submit()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值