文章目录
- 线程-并发编程
- 一、进程&&线程
- 1、进程
- 2、线程
- 3、线程与进程的比较
- 4、为什么要引入线程
- 5、引入线程的好处
- 二、Java中的线程
- 1.Java中的线程在代码中如何体现
- 2、如何在代码中创建线程
- 3、如何启动线程
- 4、什么时候会出现线程调度
- 总结
一、进程&&线程 1、进程
OS进行资源分配(不包含CPU资源)和调度的基本单位
进程的两个基本属性:
- 资源的拥有者
- 调度单位
这两个属性是构成进程并发执行的基础。
2、线程进程中的一个运行实体,CPU调度的基本单位(含CPU资源)
线程将进程的两个属性分开处理。
3、线程与进程的比较
- 调度:线程是独立调度的基本单位,进程是资源拥有的基本单位。
- 并发性:线程可以在进程内并发。
- 拥有资源:线程基本不拥有资源,进程拥有资源。
- 系统开销:线程开销小。
由于进程这一个概念天生就是资源隔离的,所以进程之间进行数据通信注定是一个高成本的工作。现实中,一个任务需要多个执行流一起配合完成,是非常常见的。所以,需要一种方便数据通信的执行流概念出来,线程就承担了这一职责。
5、引入线程的好处- 创建和销毁一个线程花费时间少;
- 两个线程的切换花费时间少;
- 线程之间相互通信无须调用内核(同一进程内的线程共享内存和文件);
- 适合多处理机系统;
OS针对同一个进程下的线程实行“连坐”机制:一旦一个线程异常退出,OS会关闭该线程所在的整个进程
二、Java中的线程 1.Java中的线程在代码中如何体现接下来的所有学习针对的都是JVM中规定的线程。
" Java线程”vs "OS线程(原生线程)“
不同JMM有不同的实现,它们的外在表现基本一致,除了极个别的几个现象。Java线程,一个线程异常关闭,不会连坐。我们使用的HotSpot实现(JVM)采用,使用一个OS线程来实现一个Java线程。
Java中由于有JVM的存在,所以使得Java中做多进程级别的开发基本很少。Java 中的线程还克服了很多OS线程的缺点。所以,在Java开发中,我们使用多线程模型来进行开发,很少使用多进程模型。
众所周知,Java是面向对象语言,所以Java中的线程就是java.lang.Thread 类(包括其子类)的一个对象。
2、如何在代码中创建线程- 通过继承 Thread 类,并且重写 run 方法,然后实例化该类的对象,就能得到一个 Thread 对象。
public class creatThread1 extends Thread{
//1、继承 java.lang.Thread 类
//2、继承之后,线程中一条指令也没有,所以要给线程写上他要执行的指令,也就是重写run方法的过程
@Override
public void run() {
//在这个方法下写的所有代码,如果正确创建线程的话,都会运行在新的线程执行流中。
System.out.println("通过继承Thread类,覆写run方法来创建进程");
}
public static void main(String[] args) {
creatThread1 t=new creatThread1();
t.start();
}
}
- 通过实现 Runable 接口,重写run方法,实例化 Runable 对象,利用 Runable 对象区构建一个 Thread 对象。
public class createTask implements Runnable{
//1、实现 Runnable 接口,
//2、通过重写 run 方法,来指定任务要做的工作,至于这个线程要不要交给一个新的线程去执行,我们是完全不知道的
public createTask() {
System.out.println("可以正常的使用构造方法之类的");
}
@Override
public void run() {
System.out.println("通过实现Runnable接口,覆写run方法,然后实例化Runnable对象,利用Runnable对象去构建一个线程");
}
public static void main(String[] args) {
createTask task=new createTask();//创建一个任务对象
Thread t=new Thread(task);//创建一个线程对象,把task任务作为Thread的构造方法传入,语句就运行在新的线程中。
t.start();
}
}
Thread:就是一个线程
Runable:让某个线程去完成的任务
作为程序员或者Java应用程序来说,我们只有 Thread 对象,通过Thread对象来控制线程的一切。
调用 Thread 对象的 start() 方法。上面代码部分有哦
注意:
1、一个已经调用过 start() 的线程就不能再调用 start() 了,再调用会抛异常,因为 start() 方法只执行在线程新建状态下。
2、千万别调成 run() 方法哈家人们✋,调成 run() 方法就和线程没关系了,就是普通的方法调用了。
- 1、CPU空闲
- 当前运行着的线程执行结束了(运行->结束)
- 当前运行的线程等待外部资源(运行->阻塞)
- 当前运行的线程主动放弃CPU(运行->就绪)
- 2、被调度器主动调度
- 1、高优先级线程抢占CPU
- 2、时间片耗尽(最常见的情况)
不同线程之间执行顺序的问题:
哪个线程先执行,哪个线程后执行,是不确定的。
start() 方法的作用就是将该线程从新建状态变成就绪状态,线程就被加入到线程调度器的就绪队列中,队列中所有的线程都在等待被调度器选中分配CPU,所以从线程进入到就绪队列这一刻起,所有的线程就是完全平等的,哪个线程被选中分配CPU就完全听天由命了。
总结
以上就到这儿吧,拜拜✋



