线程基础

进程与线程

进程

简介:一个正在进行的程序

从内存的角度看,当程序运行时,系统会为其分配一定的运行空间(运行内存上),这片空间就是进程

线程

简介:代码的一条执行路径

1、Java程序在运行时自带一条线程,这条线程称为主线程(main线程)
2、一个进程中可以有多个线程
3、从宏观上考虑多个线程是同时执行的,但从微观上考虑,多个线程在抢夺CPU执行权,谁抢夺谁执行一句代码,然后重新抢夺,所以微观考虑他们是交替执行的,因为抢夺Cpu执行权的速度很快,所以说宏观上是同时执行的。
4、除在主线程外其他线程都称为子线程

进程与线程的关系

1、一个进程可以有多个线程
2、一个进程至少有一个线程,如果一个线程都没有,那么该进程执行结束,进程将被销毁
3、进程间不能共享临时数据,多个线程之间可以共享临时数据
4、本质上进程是一个程序的运行空间,线程是代码的一条执行路径

线程组成

1、CPU时间片:抢夺到CPU执行权后,允许执行的时长
2、运行数据
	1、堆:多个线程之间共享,存储的是对象的内存
	2、栈:每个线程拥有独立的栈,局部变量,调用的方法
3、线程的逻辑

线程的创建方式

方案一:创建Thread的子类对象

方式一:
	1、找一个类继承于Thread
	2、重写run方法
	3、创建该类对象
语法:
	//步骤一:创建一个类继承于Thread
	访问量权限修饰符 class 类名 extends Thread{
		//步骤二:重写run方法
		public void run(){
			//线程启动后执行的代码
		}
	}
	//步骤三:创建该类的对象
	类名 对象名 = new 类名();
	
方式二:
	1、创建一个继承于Thread的匿名内部类对象
	2、重写run方法
语法:
	Thread 对象名 = new Thread(){
		public void run(){
			//线程启动后执行的代码
		}
	}

方案二:将线程执行的任务(Runnable)与线程对象(Thread)拆分

方式一:
	1、找一个类实现Runnable接口
	2、重写run方法
	3、创建Thread类对象并传入实现Runnable接口的子类对象
语法:
	//步骤一:创建类实现Runnable接口
	访问量权限修饰符 class 类名 implements Runnable{
		//步骤二:重写run方法
		public void run(){
			//线程启动后执行的代码
		}
	}
	//步骤三:创建该类的对象
	类名 对象名 = new 类名();
	//步骤四:在创建Thread对象时传入该类对象
	Thread thread = new Thread(对象名);
	
	可以合并步骤三与步骤四,合并效果如下:
	Thread thread = new Thread(new 类名());
	
方式二:
	1、创建Thread类对象
	2、在其实参中传入实现了Runnable接口的匿名内部类对象,重写run方法
语法:
	Thread thread = new Thread(new Runnable(){
		public void run(){
			//线程启动后执行的代码
		}
	});
	
	
建议使用方案2:
	类只能单继承,但是接口可以多实现

线程的启动

语法:
	线程对象.start();
注意:
	使用线程对象调用run方法没有开启执行路径,所以不算是一个线程

线程的消亡

线程中run方式执行完毕后,线程就等待被gc回收
注意:线程被启动后只能等待run方法执行结束,才能结束

线程的名称

设置名称:
	线程对象.setName(线程名称);
	注意:在线程启动前设置
获取名称:
	String 变量名 = 线程对象.getName();

获取当前线程

语法:
	Thread 线程对象 = Thread.currentThread();

线程的休眠

语法:
	Thread.sleep(休眠时间单位毫秒);
	
注意:线程在休眠的时候,不参与抢夺CPU执行权,在线程中使用
作用:让该线程阻塞一会,阻塞期间不抢夺CPU执行权

线程的合并

语法:
	线程对象A.join();

作用:在A线程中使用B线程对象调用join方法,就是将B线程未执行完的任何合并到A线程中,那么当B合并到A中后,先执行完B中剩余的任务,再执行A中剩余的任务

线程的礼让

语法:
	线程对象.yield();

注意:当线程获取到CPU执行权后,释放CPU执行权,再次参与抢夺

线程的优先级

作用:增大或减小线程获取到CPU执行权的概率

语法:
	线程对象.setPriority(优先级);
	
注意:
	1、需要在线程启动前设置
	2、优先级取值范围:1~10

守护线程

又名:后台线程
一般线程默认为前台线程

注意:一个进程中所有前台线程执行完毕后,进程也将被销毁,当进程销毁时,所有守护线程也将被销毁

语法:
	线程对象.setDaemon(true/false);
注意:线程启动前设置

名词

主线程:程序自带的线程
子线程:除了主线程以外的其他线程

守护线程:设置setDaemon(true/false)的线程
前台线程:没有设置setDaemon(true/false)的线程
后台线程:就是守护线程

线程的状态

初始状态:New
	线程对象没有调用start方法之前
就绪状态:Ready
	线程可以抢夺CPU执行权
运行状态:Running
	线程获取到CPU执行权,正在执行代码
终止状态:Terminated
	线程执行完run方法中的所有代码后
等待状态:Waiting
	有限期等待:Time Waiting
		如:线程调用休息方法
	无限期等待:Waiting
		如:线程调用join方法