首先说说并发这个专业名词。
什么是并发啊?并发呢说起来特别简单,就是“同时”做某些事。举个现实生活中的例子:我在烧水的时候还可以洗菜。这就是并发。你在用QQ聊天的时候同时在听着音乐,这就是并发。为什么是我要在“同时”上打引号呢?因为,对于计算机来讲,并发并不是真的“同时”,只是看似“同时”。这个又是什么意思呢?大家都知道为什么计算机能流行起来就是因为它能处理数据的速度超级快,这个快是超级快,超人的那个超,其实计算机的“同时”只是在变个魔术,它再用超人的快来欺骗的你的感官。不知道大家有没有碰到过这种情况。在有些时候你在计算机上开着好几个大型软件,然后在这些软件之间来回切换的时候,会经常卡住,再等一会就把程序切回来给你了。这个其实就是计算机不经意间在像人们展示并发的实质。计算机在运行多个软件的时候,你没在一直利用的软件会处于假死状态,计算机会把软件当前的数据状态压在栈中,当你切回的时候,再把这个软件的数据和状态从栈中弹出(原路返回)。因为这个压栈出栈的操作计算机在处理的时候会特别快,快到你用肉眼区别不出来,这个时候就形成了看上去的“同时”。
回到主题,继续来唠唠线程,提到线程,就必须先来说说进程。
进程这个名词,相信很多人都听说过,我们在电脑上打开任务管理器的时候,就可以看到有“进程”的字样。那么到底是什么是进程呢?可以这么理解,进程就是操作系统下的程序(软件),比如你在windows上运行QQ,运行游戏等,这些程序都是进程。
那么什么是线程呢?线程就是进程下的“进程”,这是什么意思呢?操作系统在启动一个进程的时候,操作系统会给这个进程开辟一部分资源给这个进程,那么在运行这个程序的时候,又需要“同时”的 干某件事(比如:在利用播放器播放视频,需要将画面和声音同时播放),这样是不是操作系统又得给这些同时干的事分配几个“进程”啦?这当然是不可能的,因为操作系统 只有一个,分配这么多还不得累死!这个时候,进程就说话了,“老操啊”(操作系统),这是我的地盘,你就不用管啦,我的地盘我做主!我自己来管理,你就管管我管管其他进程就可以啦。
像这种处理进程内部并发事件的,就叫做线程。
举个极端的例子,我某天自己瞎捉摸,想自己开发一套操作系统。于是啊,我就在自己的笔记本上开始敲代码(假如用java写) ,我笔记本的操作系统就对JVM说“我给你分配一些资源,你自己玩去吧!”可是我写的时候发现一个问题,我写的系统总得并发处理事件吧。总不能我写出来的系统在聊QQ的时候不能听音乐,在听音乐的时候不能看网页。这种操作系统用起来会让人特别的不爽。所以我也得让我自己的操作系统可以“同时”处理多个进程啊。于是我想到用JVM的线程,来当我的操作系统的进程。那么,这个时候问题就来了,在我写的操作系统中“同时”可以处理多个任务,这个时候应该叫什么呢?是线程还是进程呢?其实答案很简单。在我的笔记本上测试操作系统的时候,这个时候应该称呼为线程了。因为是在JVM这个进程下的啊!那么对于我在操作程序上跑的软件来说呢?他们就是进程。
线程的概念说完了,我们在来看看线程的状态,一张图搞定:
好了,把这写概念解释完毕后,我们再回到代码中来,从代码中理解线程的真谛!
线程的两种创建形式:
第一种创建形式:继承Thread,重写run方法
/**
* 线程
* 可以并发执行多个任务
* 线程有两种创建方式
* 方式一:直接继承Thread并重写run方法,在其中定义当前线程只想的任务
*
* @author Analyze
* thread:线
*
*/
public class ThreadDemo1 {
public static void main(String[] args) {
Thread t1=new MyThread1();
Thread t2=new MyThread2();
/*
* 需要注意,启动线程要调用start方法,不要调用run方法,
* run方法是线程要执行的任务,start调用完毕后,线程纳入到线程调度中,线程调度会分配CPU时间片来运行该程序,
* 当线程运行时会自动调用run方法,
* start方法调用完毕后run方法很快的启动起来,但绝对不是start方法运行过程中的run方法被执行
*/
t1.start();
t2.start();
}
}
/*
* 第一种创建线程方式有两个不足:
* 1.由于要求继承Thread类,那么在将来项目中,就有可能出现继承冲突。
* 很多时候我们需要继承项目中的一个父类来复用方法,但是当前类又需要继承Thread作为一个线程去使用时,
* java是单继承的,这里就产生了冲突
* 2.由于继承Thread后需要重写run方法来定义线程要执行的任务,这就导致线程与任务有一个强耦合关系,
* 当前线程就只能做run方法中定义的任务,其他事情做不了,这不利于线程的重用
*/
class MyThread1 extends Thread{
public void run(){
for(int i=0;i<100;i++){
System.out.println("你是谁啊?");
}
}
}
class MyThread2