多线程基础(一)
1、进程:进程是资源(CPU、内存等)分配的基本单位,它是程序执行时的一个实例。程序运行时系统就会创建一个进程,并为它分配资源,然后把该进程放入进程就绪队列,进程调度器选中它的时候就会为它分配CPU时间,程序开始真正运行。
2、线程:线程是程序执行时的最小单位,它是进程的一个执行路径,是CPU调度和分派的基本单位,一个进程可以由很多个线程组成,线程间共享进程的所有资源,每个线程有自己的堆栈和局部变量。线程由CPU独立调度执行,在多CPU环境下就允许多个线程同时运行。
3、多线程的好处:提升程序效率。
4、多线程的创建方式:
①继承Thread类,重写run方法
public class CreateThreadOneTest {
public static void main(String[] args) {
CreateThreadOne t1 = new CreateThreadOne();
t1.start();
for (int i = 0; i < 10; i++) {
System.out.println("我是主线程 : " + i);
}
}
}
class CreateThreadOne extends Thread {
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("我是子线程 : " + i);
}
}
}
②实现Runnable接口,重写run方法
public class CreateThreadTwoTest {
public static void main(String[] args) {
Thread t1 = new Thread(new CreateThreadTwo());
t1.start();
for (int i = 0; i < 10; i++) {
System.out.println("我是主线程 : " + i);
}
}
}
class CreateThreadTwo implements Runnable {
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("我是子线程 : " + i);
}
}
}
5、那种方式好? 使用实现实现Runnable接口好,原因是Java单继承,多实现。实现了接口还可以实现,继承了类不能再继承。
6、启动线程是使用调用start方法还是run方法? start方法。
7、多线程有几种状态?
可以查看Thread里面的状态枚举类State,可以看到六种状态:NEW(新创建)、RUNNABLE(可运行)、BLOCKED(被阻塞)、WAITING(等待)、TIMED_WAITING(计时等待)、TERMINATED(被终止)。
8、线程的分类:用户线程、守护线程(后台线程)。
这里有几个点要注意:
①java程序中一定存在的线程是主线程。
②主线程不是守护线程。以下代码运行结果为false
public class TestMainThread {
public static void main(String[] args) {
System.out.println(Thread.currentThread().isDaemon());
}
}
③GC线程就是守护线程
④主线程停止,用户线程不会停止
⑤在一个进程中如果只剩下 了守护线程,那么守护线程也会死亡。下面是验证例子:
public class TestDeamanThread {
public static void main(String[] args) {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
while (true) {
try {
Thread.sleep(100);
System.out.println("我是守护线程...");
} catch (Exception e) {
}
}
}
});
//设置为主线程,要在start之前设置
thread.setDaemon(true);
thread.start();
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
try {
for (int i = 0; i < 10; i++) {
Thread.sleep(1000);
System.out.println("我是用户线程 : " + i);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
t2.start();
for (int i = 0; i < 10; i++) {
try {
Thread.sleep(100);
} catch (Exception e) {
}
System.out.println("我是主线程 : " + i);
}
System.out.println("主线程执行完毕!");
}
}
9、Thread Api
①join方法作用:等待该线程终止。同时把执行权让给该线程,如先让子线程执行完毕后,在执行主线程(要在start之后使用才有效),代码如下:
public class TestJoin {
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(()-> {
for (int i = 0; i < 10; i++) {
System.out.println("我是子线程 : " + i);
}
});
t1.start();
//要在start之后使用才有效
t1.join();
for (int i = 0; i < 10; i++) {
System.out.println("我是主线程 : " + i);
}
}
}