一、进程
进程
要说线程,首先先说进程,线程是依赖于进程存在的。进程就是正在运行的程序,是系统进行资源分配和调用的独立单位。每一个进程都有它自己的内存空间和系统资源。
多进程的意义
单进程计算机只能做一件事情,而我们现在的计算机都可以同时完成多见事情,所以我们常见的操作系统都是多进程操作系统。但对于多核计算机来讲,各个进程并不是同时进程的,因为CPU在某个时间点上只能做一件事情,计算机是在各个进程之间做着频繁切换,且切换速度很快。
多进程的作用不是提高执行速度,而是提高CPU的使用率。
二、多线程
概述
在一个进程内部又可以执行多个任务,而这每一个任务我们就可以看成是一个线程。是程序使用CPU的基本单位。
多线程的意义
多线程的作用不是提高执行速度,而是为了提高应用程序的使用率。
我们程序在运行的使用,都是在抢CPU的时间片(执行权),如果是多线程的程序,那么在抢到CPU的执行权的概率应该比较单线程程序抢到的概率要大.那么也就是说,CPU在多线程程序中执行的时间要比单线程多,所以就提高了程序的使用率.但是即使是多线程程序,那么他们
中的哪个线程能抢占到CPU的资源呢,这个是不确定的,所以多线程具有随机性。
三、多线程程序实现(方式1)
1、继承Thread类
2、重写run方法
3、使用start方法启动线程
Thread类的基本获取和设置方法:
public final String getName()//获取线程名称
public final void setName(String name)//设置线程名称
下面通过代码演示一下
public class Test extends Thread{
public static void main(String[] args) {
Test test = new Test();
test.setName("第二");
test.start();
for (int i = 0; i < 5; i++) {
System.out.println("主线程启动了"+i);
}
}
@Override
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName()+"线程启动了"+i);
}
}
}
主线程启动了0
主线程启动了1
主线程启动了2
主线程启动了3
主线程启动了4
第二线程启动了0
第二线程启动了1
第二线程启动了2
第二线程启动了3
第二线程启动了4
可以看到,程序并不是顺序执行的,因为主线程启动的快,直接运行结束,然后才轮到第二线程
线程调度及获取和设置线程优先级
线程有两种调度模型:
分时调度模型 所有线程轮流使用 CPU 的使用权,平均分配每个线程占用 CPU 的时间片
抢占式调度模型 优先让优先级高的线程使用 CPU,如果线程的优先级相同,那么会随机选择一个,优先级高的线程获取的 CPU 时间片相对多一些。
Java使用的是抢占式调度模型。
public final int getPriority() //获取线程的优先级
public final void setPriority(int newPriority)//设置线程的优先级,默认为5,最高为10,最低为1
用代码测试一下
public class Test2 extends Thread{
public static void main(String[] args) {
Test2 test21 = new Test2();
Test2 test22 = new Test2();
Test2 test23 = new Test2();
Test2 test24 = new Test2();
Test2 test25 = new Test2();
test21.setPriority(1);
test21.setPriority(5);
test21.setPriority(6);
test24.setPriority(9);
test25.setPriority(10);
test21.start();
test22.start();
test23.start();
test24.start();
test25.start();
}
@Override
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName()+"线程启动了");
}
}
}
结果:
Thread-4线程启动了
Thread-3线程启动了
Thread-4线程启动了
Thread-3线程启动了
Thread-4线程启动了
Thread-3线程启动了
Thread-4线程启动了
Thread-3线程启动了
Thread-4线程启动了
Thread-3线程启动了
Thread-0线程启动了
Thread-0线程启动了
Thread-0线程启动了
Thread-0线程启动了
Thread-0线程启动了
Thread-1线程启动了
Thread-1线程启动了
Thread-1线程启动了
Thread-1线程启动了
Thread-1线程启动了
Thread-2线程启动了
Thread-2线程启动了
Thread-2线程启动了
Thread-2线程启动了
Thread-2线程启动了
可以看到,优先级高的并不一定比优先级低的线运行,但可以说,优先级越高,先运行的概率就越大。
线程控制之休眠线程
线程休眠可让当前正在运行的线程暂停一会,让其他线程先执行,休眠时间可随意设置
public static void sleep(long millis) 线程休眠
代码演示
public class Test3 extends Thread{
@Override
public void run() {
for (int i = 0; i < 5; i++) {
//在循环执行到第三此时,我们让第一线程休息100ms
if(i==2&Thread.currentThread().getName().equals("第一")){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName()+"线程执行了");
}
}
public static void main(String[] args) throws InterruptedException {
Test3 test1 = new Test3();
Test3 test2 = new Test3();
test1.setName("第一");
test2.setName("第二");
test1.start();
test1.sleep(100);
test2.start();
}
}
结果:
第一线程执行了
第一线程执行了
第二线程执行了
第二线程执行了
第二线程执行了
第二线程执行了
第二线程执行了
第一线程执行了
第一线程执行了
第一线程执行了
线程控制之加入线程
加入线程: public final void join()
意思就是: 等待该线程执行完毕了以后,其他线程才能再次执行
注意事项: 在线程启动之后,在调用方法
代码演示:
public class Test4 extends Thread{
public static void main(String[] args) {
Test4 test = new Test4();
for (int i = 0; i < 1000; i++) {
if(i==3){
test.start();
}
System.out.println("主线程执行"+i);
}
}
@Override
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println("线程插队");
}
}
}
结果就不演示了,你可以复制代码自己去运行几次,加入的线程会开始启动,这时候如果你电脑运行速度够快也许会让加入的线程赶不到主线程之前开始运行,所以可让多线程多运行一会看看效果