一,基础
1.1线程的概述
进程
进程是计算机的程序关于某数据集合上的一次运行活动,是操作系统进行资源分配与调度的单元|
可以简单的理解为在操作系统上运行的一个程序
线程
线程是进程的一个执行单元,一个线程就是进程中的一个单一顺序的控制流,进程的一个执行分支。
进程与线程的关系
进程是线程的容器,一个进程至少有一个线程,一个进程中也可以有多个线程。
在操作系统中是以进程为单位分配资源,如虚拟机存储空间,文件描述符等。每个线程都有各自的线程栈,自己的寄存器环境,自己的线程本地存储。
主线程和子线程
JVM启动时会创建一个主线程,该主线程负责执行main方法,简单来说主线程就是运行main方法的线程。
java中的线程不是孤立的,线程之间存在一些联系,如果我们在A线程中创建了一个B线程,称B线程为A线程的子线程,相应的A线程就是B线程的父线程
串行,并发与并行
并发可以提高对事务处理效率。
并行是一种更为严格,理想的并发。
从硬件的角度来说,如果单核CPU,一个处理器一次只能执行一个线程的情况下,处理器可以用时间片轮转技术,可以让CPU快速的在各个线程之间进行切换,对于用户来说,感觉就是三个线程在同时执行。可以为不同的线程分配不同的CPU内核
1.2线程的创建与启动
在java中,创建一个线程就是创建一个Thread类(子类)的对象(实例)
Thread类有两个常用的构造方法:Thread()与Thread(Runnable)。 对应的创建线程 两种方式(两种创建方式没有本质的区别): 定义Thread类的子类 定义一个Runnable接口的实现类
方法一:定义Thread类的子类
public class MyThread extends Thread {
// 重写run方法
@Override
public void run() {
System.out.println("这是子方法");
}
}
public class Test {
public static void main(String[] args) {
System.out.println("JVM启动main线程,main线程执行main方法");
//创建一个线程对象
MyThread thread = new MyThread();
//启动线程
thread.start();
/*调用线程start()方法来启动线程,
启动线程的实质就是请求JVM运行的线程,具体什么时候运行由线程调度器决定。
注意:
start()方法调用结束并不意味着线程的开始运行
新开启的线程会执行run()方法
如果开启了多个线程,start()调用的顺序并不一定就是线程启动的顺序。
*/
System.out.println("miam的结尾");
}
}
方法二:定义一个Runnable接口的实现类
public class MyRunnable implements Runnable{
@Override
public void run() {
for (int i = 0; i <10 ; i++) {
System.out.println(i);
int time = (int) (Math.random() * 1000);
try {
Thread.sleep(time);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class Test {
public static void main(String[] args) throws InterruptedException {
//创建Runable接口的实现对象
MyRunnable myRunnable = new MyRunnable();
Thread thread1 = new Thread(myRunnable);
thread1.start();
//有时调用Thread(Runnable)构造方法时,实参也可以传递匿名内部类
Thread thread2 = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("匿名" + i);
int time = (int) (Math.random() * 1000);
try {
Thread.sleep(time);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
thread2.start();
for (int i = 0; i < 10; i++) {
System.out.println("main"+i);
int time = (int) (Math.random() * 1000);
Thread.sleep(time);
}
}
}