第14章 多线程编程

在这里插入图片描述

第14章 多线程编程

线程的基本概念
并行:CPU同一时刻运行多个任务
并发:CPU不同的代码交替的实现
进程是唯一的分配单位
运行在进程里面的多个任务就叫线程
一个正在运行的程序通常称为一个进程(Process),每个进程都有自己独立的一块内存空间,每个进程的内部数据和状态都是完全独立的。

线程创建
编写一个继承Thread类的类,然后在类中重写Thread类的run()方法
编写一个类实现Runnable接口,然后将该类的实例与java.lang.Thread对象联系在一起
通过继承Thread类来创建线程
1、创建一个继承Thread类的类
2、在创建的Thread子类中重写run()方法,在方法中写入想要线程运行的代码
3、创建Thread子类的实例
4、通过调用该实例上的start()方法,开始运行线程
通过实现Runnable接口来创建线程
创建一个类实现Runnable接口,用于代表我们需要线程完成的任务
在Runnable指定的run()方法内,放入想要在线程中执行的代码
重写run(),这里面的代码,在线程被CPU选中后,需要执行
创建一个Runnable类的实例
创建一个Thread对象,将Runnable的实例做为构造器参数传入进去
通过调用Thread类的实例的start()方法,开始执行线程
通过callable,future接口创建线程
该线程可以控制主函数运行于子线程末

线程的生命周期

新建状态:
使用 new 关键字和 Thread 类或其子类建立一个线程对象后,该线程对象就处于新建状态。它保持这个状态直到程序 start() 这个线程。
就绪状态:
当线程对象调用了start()方法之后,该线程就进入就绪状态。就绪状态的线程处于就绪队列中,要等待JVM里线程调度器的调度。
运行状态:
如果就绪状态的线程获取 CPU 资源,就可以执行 run(),此时线程便处于运行状态。处于运行状态的线程最为复杂,它可以变为阻塞状态、就绪状态和死亡状态。
阻塞状态:
如果一个线程执行了sleep(睡眠)、suspend(挂起)等方法,失去所占用资源之后,该线程就从运行状态进入阻塞状态。在睡眠时间已到或获得设备资源后可以重新进入就绪状态。
等待阻塞:运行状态中的线程执行 wait() 方法,使线程进入到等待阻塞状态。
同步阻塞:线程在获取 synchronized 同步锁失败(因为同步锁被其他线程占用)。
其他阻塞:通过调用线程的 sleep() 或 join() 发出了 I/O 请求时,线程就会进入到阻塞状态。当sleep() 状态超时,join() 等待线程终止或超时,或者 I/O 处理完毕,线程重新转入就绪状态。
死亡状态:
一个运行状态的线程完成任务或者其他终止条件发生时,该线程就切换到终止状态。

守护线程
守护(Daemon)线程是在后台运行的线程。
setDaemon(true)
setDaemon(false)

死锁
死锁的发生多半是因为程序设计不佳所造成的,主要原因是来自于对象锁无法获得。因此,当我们设计同步程序时,必须仔细考虑每个对象锁的优先顺序。

创建多线程程序
线程的优先级
线程优先级分三种,最高为10,最低为1,默认为5
yield()方法
挂起;用yield()方法让该线程让出运行权,yield()方法会让线程由Running状态直接回到Runnable状态,而不会阻塞(Blocked)一段指定的时间
sleep()方法
休眠;可以让线程休眠,休眠过后进入就绪状态
join()方法
该方法会让当前正在运行的线程暂停运行,并等待调用join()方法的线程运行完成后,才继续运行
wait( )方法 让使用对象的线程停止运行,并进入等待,直到另一个使用该对象的线程运行notify( )方法

线程同步与线程之间的相互通讯机制
线程同步
当两个以上的线程需要访问共享资源时,我们必须确定在同一时间点只有一个线程能够存取共享资源,而运行这个目标的过程就称为同步
同步块

要设计同步块程序,我们可以使用Synchronized关键字
synchronized 如果用于修饰 对象的话,修饰对象时,除了可以修饰本对象之外,还可以修饰其他对象,//表示的含义是:开启对象本身的对象锁,当多根线程同时访问该对象,谁抢的了该对象锁,谁就可以访问同步块的代码
synchronized 修饰类对象时候, 此时表示开启Class对象的对象锁 //当多根线程同时访问同步块时,谁抢的了该Class对象的对象锁,谁就可以访问同步块的代码
synchronized 也可以用来修饰成员方法,同样开启“自身对象”的对象锁,当多根线程同时访问该方法时,谁抢的了该对象锁,谁就可以访问该对象的这个方法
synchronized 还可以修饰类方法,修饰类方法的时候, 此时开启的Class对象的对象锁,当多根线程同时访问该方法时,谁抢的了该Class对象的对象锁,谁就可以访问该类的这个类方法
如何选择同步块, 或者同步方法呢?
1、方法的执行范围,一定比其中的某一段代码执行范围要大的多(锁的范围越大,能够操作代码的人,就越少)
2、同步方法开启的对象锁,只能是本对象的,那如果需要开启其他对象的呢?

同步方法
要设计同步方法程序,我们可以在方法定义时,在方法名前面使用Synchronized关键字修饰即可
同步块比同步方法实用,因为方法比一段代码大

线程之间的相互通讯

	Java中提供了wait()、notify()和notiyAll()三个方法用于线程之间的相互通讯,用于解决上述问题,这种机制称为“监控器模型(Monitor Model)
	**wait()方法**
		让使用对象的线程停止运行,并进入等待,直到另一个使用该对象的线程运行notify()方法
	**notify()方法**
		线程在对象中碰到notify()方法时,会唤醒使用相同对象的第一个碰到wait()的线程
	**notifyAll()方法**
		线程在对象中碰到notifyAll()方法时,会唤醒使用相同对象的所有线程,并让优先权最高的线程准备运行
	该机制的主要目的是在保证共享数据的一致性,并预防程序进入死锁的状态
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值