线程基础
1.进程和线程
进程:是指运行中的程序,比如我们使用QQ,就启动了一个进程,操作系统就会为该进程分配内存空间。进程是程序的一次执行过程,或是正在运行的一个程序。是动态过程: 有它自身的产生、存在和消亡的过程
线程:由进程创建的,是进程的一个实体,一个进程可以拥有多个线程
2.并发和并行
并发:同一个时刻,多个任务交替执行,造成一种“貌似同时”的错觉,简单的说,单核cpu实现的多任务就是并发。
并行:同一个时刻,多个任务同时执行。多核cpu可以实现并行
3.创建线程的两种方式
3.1 继承Thread类,重写run方法
这种方式创建线程,需要继承Thread类,然后重写run方法,在run方法里面写上想实现的业务逻辑,这里让其每隔一秒在控制台输出“喵喵叫”,在main方法里实例化Cat对象,调用start方法启动线程。
public class Thead01 {
public static void main(String[] args) {
Cat cat = new Cat();
cat.start();
}
}
class Cat extends Thread{
@Override
public void run() {
while (true){
try {
Thread.sleep(1000); //让该线程休眠一秒
System.out.println("喵喵叫~");
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}
Thread,意为线程,Thread类实现了Runnable接口,重写了里面唯一的run方法,但是里面的run方法由于target属性为null,并没有执行实现了Runnable接口的run方法。所以我们需要重写Thread类的run方法,就会执行我们需要的逻辑
3.2 实现Runnable接口,重写run方法
java是单继承的,在某些情况下一个类可能已经继承了某个父类,这时在用继承Thread类方法来创建线程显然不可能了。java设计者们提供了另外一个方式创建线程,就是通过实现Runnable接口来创建线程。
public class Thead02 {
public static void main(String[] args) {
Thread thread = new Thread(new Dog());
thread.start();
}
}
class Animal{
}
class Dog extends Animal implements Runnable{
@Override
public void run() {
System.out.println("汪汪汪~");
}
}
调用thread.start()后,会调用start0方法,start0是一个本地方法,由JVM调用,底层是c/c++实现。真正实现多线程的效果是由start0()实现的,而不是run,也就是说,在执行start0的过程中,会来回调实现了Runnable接口的run方法。run方法只是一个普通方法,直接调用run就是串行顺序执行的效果。
start() 方法调用 start0()方法后,该线程并不一定会立马执行,只是将线程变成了可运行状态。具体什么时候执行,取决于 CPU,由 CPU 统一调度。
4.线程终止
1)当线程完成任务后,会自动退出。
2)还可以通过使用变量来控制run方法退出的方式停止线程,即通知方式
下面改造第一个例子用第二种方式终止线程:
public class Thead03 {
public static void main(String[] args) {
Cat cat = new Cat();
cat.