作者主页:paper jie_博客
本文作者:大家好,我是paper jie,感谢你阅读本文,欢迎一建三连哦。
本文录入于《vaEE》专栏,本专栏是针对于大学生,编程小白精心打造的。笔者用重金(时间和精力)打造,将MySQL基础知识一网打尽,希望可以帮到读者们哦。
其他专栏:《MySQL》《C语言》《javaSE》《数据结构》等
内容分享:本期将会分享多线程知识~
前言
在上篇文章中,我们提到了多进程这个概念,通过多进程我们就可以同时多次运行多个程序了.但是,这这里其实还是有一个比较明显的缺点.就是进程在创建的时候需要申请资源,销毁的时候需要释放资源.这就会导致开销比较大.再这个前提下,就延伸出了多线程这个概念.
多线程
什么是多线程
多线程也可以叫轻量级进程.一个进程是可以包含多个线程的,且至少得有一个线程.线程也可以单独执行,每个线程都有一个自己的PCB,有一些支持调度的重要属性,比如状态,优先级,记账信息,上下文等. 多线程主要就是为了解决进程申请资源和释放资源开销大的这个问题.且它也可以提高一个进程的效率.多线程是Java常用的编程方式.
为什么多线程可以解决多进程开销大的问题
这是因为一个进程中的所有线程他们的资源是共享的.随着进程创建好,第一个线程也随着创建好了,第一个线程创建的时候会申请好资源,再后面随着创建好的线程都会共用这份资源.这样就意味着,除了第一个线程需要申请和释放资源外,其他的线程都不用在申请资源了.但这不是随便两个线程就可以共享.这需要一组相关的线程才可以,这就叫做线程组.
如果在深究下去的话,为什么它们能资源共享?这是因为线程中会有内存指针这样的属性,它们的内存指正指向的都是同一块内存,这块内存就是第一个线程申请过来的.硬盘资源也是如此,它们也会有一个文件操作符表,是用来操作硬盘资源的.它们表示的也是同一份硬盘资源.
这里就可以得出一个概念: 在多线程中,进程是分配资源的基本单位. 线程是调度执行的基本单位.
多线程的缺点
多线程也不是十全十美的,它也有一些缺点.线程不是越多越好,太多了会导致调度开销比较大. 且进程与进程之间是相互独立的,但是多线程中,一个线程挂了,这个进程中的其他线程有可能也会随着异常中断.
进程与线程的区别
1. 一个进程包含多个线程,且最少有一个线程.
2. 进程是资源分配的基本单位,线程是调度执行的基本单位.
3. 进程间的资源是独立的,但一个进程内的线程是共享资源的.
4.线程也是一单独的执行流,它也有PCB,里面也有状态,优先级,记账信息,上下文
5. 进程与进程间是相互独立,互不干扰的.但是一个进程中,一个线程挂了,其他线程也可能异常中断.
6. 线程不是越多越好,需要适量.不然调度开销会比较大.
7. 线程与线程间可能会相互干扰,会有线程安全问题.
Java中的多线程
线程是操作系统的概念.操作系统内核中实现了线程这样的概念.且对用户提供了统一的API供用户使用.但是这些API大多是拿C/C++写的.在这个前提下,Java标准库中对操作系统的API进行了进一步的抽象与封装. 在Java中表示线程就是用Thread这个类.
第一个多线程程序
Thread就是Java提供的API.在创建一个类后需要继承Thread,再重写他的run方法.run方法是这个线程的入口. 还需要创建实例,这才是一个线程.最后需要使用start方法,它是真正的在内核中创建了线程.
class MyThread extends Thread {@Override//run方法就是这个线程的入口方法public void run() {System.out.println("进去执行啦");}
}public class ThreadDemo {public static void main(String[] args) {//创建实例 线程实例才是真正的线程MyThread myThread = new MyThread();//开始执行 调用Thread的start才是真正的调用系统 api,在系统内核中创建线程myThread.start();}
}
什么是内核
内核就是用来管理管理硬件资源,为软件提供稳定的运行环境.操作系统可以简单的认为是 内核 + 配套的应用程序. 操作系统里面分为内核态和用户态.一般我们的应用程序都是运行在用户态中.但再需要使用硬件资源时,不能直接对硬件资源操作,就需要通过操作系统提供的API进一步在内核中操作.
为什么要划分出内核态和用户态
目的就是为了稳定.为了防止程序把硬件资源,软件资源搞坏了.系统提供的API是合法的.应用程序只能调用这些API,就不会对操作系统或资源造成极大的伤害. 因为在一些极端的情况下程序直接操作硬件可以会将硬件烧坏.
我们可以将操作系统想象成银行,办事窗口是内核区,大厅是用户区.大厅的滑稽需要存钱或者取钱需要通过窗口的工作人员来处理,不能自己直接进去拿.
多线程与普通程序的区别
多线程和普通程序的区别就是每个线程都是一个独立的执行流,他们都是并发执行的,并不是顺序执行代码.
栗子:
class MyThread extends Thread {@Overridepublic void run() {while(true) {System.out.println("hello Thread");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}}
}
public class ThreadDemo1 {public static void main(String[] args) {Thread t = new MyThread();t.start();while(true) {System.out.println("hello main");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}}
}
通过代码执行打印效果,我们可以发现并不是先打印hello THread在打印 hello main,而是同时执行打印,且是随机的.因为内核中有一个调度器模块.实现方式就是随机调度的效果.
使用jconsole命令观察线程
在本地上找到jbk的bin,再找到jconsole这个可执行文件,双击打不来可以用管理员运行方式打开.
我们可以在线程这一栏中观察我们创建的线程.