一、 进程与线程
在谈论线程之前,我们先来看看什么叫进程,以及进程与线程的关系。
进程
我们在windows操作系统中打开任务管理器,可以看到有一项是“进程”,里面列举出了用户目前正在运行的所有进程,包括系统进程和用户应用程序进程,以及每个进程所占用的内存资源等信息。进程是操作系统结构的基础,它不仅只包括运行的程序代码,还包括当前的活动。对于每一个进程,操作系统都会为其分配一个独立的内存块,各进程间资源是不共享的。
划分时间片,宏观上并行,微观上串行
线程
一个Java程序运行之后,就会启动一个JVM实例进程,这个进程就负责处理这个程序所有的操作,直到程序结束,进程也随之结束。
而线程就是再在进程的内部将CPU资源进行再次划分,以满足同时处理多条语句的需要(微观上,其实也是并行执行的),这些线程在进程内部的资源是共享的(正因如此,才会有同步以及锁的出现)。
JVM进程启动一定会有一个主线程存在,即main方法启动的线程,这个线程是Java程序的入口,我们可以在main方法内部在定义我们自己的线程,这样就可以实现多线程了。
二、 Java多线程的实现方式
java.lang.Thread类的一个对象就代表一个线程
线程是底层OS(操作系统)维护的资源,JVM跑在OS上,在JVM中创建一个Thread对象,调用其start()方法,底层OS会申请一个线程资源,线程对象可到底层管理一个线程,创建好线程之后,把要让线程执行的代码封装到线程对象中(覆盖run()方法)。
实现线程代码的方式:
1、继承Thread类,覆盖run()方法
去底层申请线程并运行,对线程对象调start()方法,main方法是一个主线程
宏观并行,微观串行
2、实现Runnable接口
使用多态获得Runnable对象,成为目标对象
再利用目标对象构造线程对象Thread t = new Thread(target);//target为Runnable接口类型
三、 线程的优先级
线程的优先级是从0-10的整数,0表示最低,5表示普通,10表示最大;JVM会自动将java线程的优先级转换为操作系统的优先级。
main线程的优先级是5。
四、 线程的状态
下面为线程中的7个非常重要的状态(有的书上也只有认为前五种状态:而将“锁池”和“等待池”都看成是“阻塞”状态的特殊情况:这种认识也是正确的,但是将“锁池”和“等待池”单独分离出来有利于对程序的理解):
1、 初始状态:线程刚创建(Thread th = new Thread(target);)
2、 可运行状态:线程创建之后调用它的start()方法,此时线程状态就变更为可运行状态,但一定就会立即运行,需要等待获得CPU。
3、 运行状态:调用线程的start()方法之后,线程就会进入等待运行状态(可运行状态),此时一旦该线程获得CPU的使用权,县城就会立即进入运行状态,即执行线程的run()方法。
4、 阻塞状态:线程失去CPU的使用权,进入一种等待状态,注意不是可运行状态。有以下三种情况会使线程进入阻塞状态:
(1) 等待外部设备输入:如等待键盘输入,则该线程会进入阻塞状态直到输入完毕,注意:阻塞结束之后是进入可运行状态,而不是运行状态。
(2) 线程休眠,即调用线程的sleep()方法。Sleep()方法有一个参数,表示休眠的时间,当线程休眠的时间到达指定时间后,线程会自动结束阻塞状态而进入可运行状态,等待CPU。
(3) 一个线程调用另一个线程的join()方法,join()方法指的是调用该方法的线程将进入阻塞状态直到被调用join()方法的线程运行结束之后,才会进入可运行状态。
例:在t2线程的run()方法内部有这样一句代码t1.join();(t1是一个线程对象),这将意味着党线程t2执行到该语句时就会调用线程t1的join()方法,从而t2进入阻塞状态,直到t1运行结束为止。
5、 终止状态:即线程执行结束
6、 锁池状态
7、 等待队列
相关阅读: