一、线程与进程概念
- 线程其实就是一条执行路径
- 进程是独立应用程序
- 进程是所有线程集合
- 多线程 同一时刻有多条不同的执行路径,同时进行执行,目的 为了提供程序效率
例如我们同时打开多个软件,每个软件就是一个进程,人为以为进程是在同时进行执行,其实是底层CPU进行不断切换,只是切换很快我们不察觉
二、多线程的应用场景
例如:迅雷软件可以支持多线程下载,但注意多线程不能提高下载速度,多线程下载只能提高程序效率
三、同步概念和异步概念
3.1同步概念
- 同步概念:代码从上往下执行也就是单线程,例如:下图在执行方法2时方法1必须要先执行完如果方法1用时10秒,方法2用时也是10秒那总共用时就是20秒,如果方法1挂了,方法2就不会再执行了
3.2异步概念
异步是新的一条执行路径,不会影响其他线程,多线程包含异步概念
四、创建线程的方式
4.1、继承thread类创建线程
//1. 继承thread类,重写run方法,run方法中,需要线程执行代码
class ThreadDemo01 extends Thread{
@Override
public void run() {
for(int i=0;i<30;i++) {
System.out.println("子线程"+i);
}
}
}
public class Test001 {
public static void main(String[] args) {
ThreadDemo01 threadDemo01 = new ThreadDemo01();
threadDemo01.start();
for(int i=0;i<30;i++) {
System.out.println("主线程"+i);
}
}
}
4.2、实现runable接口实现线程
//2.实现runable接口,重写run方法
class ThreadDemo02 implements Runnable{
@Override
public void run() {
for(int i=0;i<30;i++) {
System.out.println("子线程"+i);
}
}
}
public class Test002 {
public static void main(String[] args) {
ThreadDemo02 threadDemo02 = new ThreadDemo02();
Thread thread = new Thread(threadDemo02);
thread.start();
for(int i=0;i<30;i++) {
System.out.println("主线程"+i);
}
}
}
4.3、使用匿名内部类创建线程
//匿名内部类,重写run方法
public class Test003 {
public static void main(String[] args) {
Thread t1=new Thread(new Runnable() {
@Override
public void run() {
for(int i=0;i<30;i++) {
System.out.println("子线程"+i);
}
}
});
t1.start();
for(int i=0;i<30;i++) {
System.out.println("主线程"+i);
}
}
}
五、多线程的五种状态
六、守护线程与非守护线程
- 什么是守护线程,和main(主线程)相关,有一个特征:和主线程一起销毁
- 用户线程,用户自己创建的线程,用户创建线程,如果主线程停止掉,不会影响用户线程
- main(主线程),就有一个守护线程gc线程(垃圾回收机制)
总结:守护线程: 和主线一起销毁,非守护线程:和主线程互不影响
//守护线程
public class Test005 {
public static void main(String[] args) {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
for(int i=0;i<30;i++) {
try {
Thread.currentThread().sleep(300);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("守护线程"+i);
}
}
});
//把thread线程设置为守护线程
thread.setDaemon(true);
thread.start();
for(int i=0;i<10;i++) {
try {
Thread.currentThread().sleep(300);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("主线程"+i);
}
System.out.println("主线程结束");
}
}
输出结果:可以看出只要主线程执行完毕守护线程就不再执行下去
七、join方法介绍
//join
public class Test006 {
public static void main(String[] args) {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
for(int i=0;i<30;i++) {
System.out.println("子线程"+i);
}
}
});
thread.start();
try {
//main中的thread.join()作用是主线程让出资源给thread执行完了,才到主线程继续执行
thread.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
for(int i=0;i<30;i++) {
System.out.println("主线程"+i);
}
}
}