一个进程可以拥有多个线程,当然,也可以只拥有一个线程,只有一个线程的进程被称作单线程程序
注意:每个线程也有自己独立的内存空间,当然也有一部分公共的空间用于保存共享的数据
在宏观上,一个CPU看似可以同时处理多件事
在微观上,一个CPU同一时刻只能处理一件事
结论:线程的执行具有随机性,我们控制不了,是由OS底层的算法来决定的
4.线程有几种状态?它们是怎么转换的?
-
新建状态:new–申请PCB,进行资源的分配
-
就绪/可运行状态:万事俱备只欠CPU,其实是将创建好的线程对象加入到就绪队列中,等待OS选中,这个选择我们是控制不了的
-
执行/运行状态:就绪队列中的线程被OS选中了,正在执行
注意:只有就绪状态才能切换成执行状态
- 阻塞状态:线程在执行中遇到了问题:
锁阻塞、休眠阻塞、等待阻塞…问题解决后再加入到就绪队列中
- 终止状态:线程成功执行完毕,释放资源
线程的挂起:正在运行中的线程,由于CPU分配的时间片用完,所以需要保存当前线程运行的各项状态信息,直到CPU下次再在就绪队列中选中这个线程,恢复现场,继续执行这个线程
==================================================================================
多线程实现的方案一:继承Thread
1.定义自己的多线程类TicketThread,并且继承Thread
2.重写父类的run(),里面是我们自己的业务
3.创建多个自定义线程类对象
4.通过线程对象.start()将线程加入到就绪队列中
5.查看多线程抢占资源的效果
构造方法摘要
Thread() 创建一个新的线程对象,名字是系统自定义的
Thread(String name) 与上面功能一致,还可以自定义线程名
可以通过调用父类Thread的含参构造Thread(String name)
给自定义线程对象起名字,调用方式:super(name);
多线程实现的方案二:实现Runnable
1.定义自己的业务类,并且实现接口Runnable
2.在业务类中添加接口里的抽象方法run(),并实现业务
3.创建唯一的业务类对象
4.创建多个Thread类的对象,作为多个线程对象
并将刚刚的业务对象传入
5.使用多个线程类对象调用start(),将线程加入到就绪队列之中
6.查看多线程抢占资源的效果
构造方法摘要
Thread(Runnable target) 创建一个线程对象,参数为Runnable实现类的对象
Thread(Runnable target, String name) 与上面功能一致,还可以自定义线程名
虽然方案二写法较为复杂,但是方案二的优点如下:
-
没有继承,耦合性不强,后续仍然可以继承或者实现其他的接口 ,比较自由
-
可以给所有的线程对象统一业务,业务只需要发布一次,保持统一