什么是线程
记得小时候的电脑老是很卡,打开一个浏览器、游戏啥的老是卡死,关又关不掉,然后就会打开任务管理器,强制关闭它
我们可以看到,这个叫“进程”,简单理解一下,进程就是由(一个或多个)线程组成的,线程是操作系统进行运算调度的最小单位(进程是系统分配资源的基本单位)
进程和线程都是为了处理并发编程!线程是轻量级的进程
进程创建和销毁效率较低(需要分配资源),而线程弥补了该缺点!,
进程具有独立性,每个进程会有自己的虚拟空间,一个进程挂了不会影响另一个进程,
一个进程中的线程之间可能会互相影响,一个线程挂了甚至导致进程奔溃!!!
创建线程的n种方法
(首先我们的main函数就是一个线程)线程的创建都是围绕着Thread实例的创建展开的
创建一个重写了run方法的的Thread子类
class MyThread extends Thread{ @Override public void run() { System.out.println("我是线程"); } } public class Main { public static void main(String[] args){ MyThread thread = new MyThread(); thread.start(); } }
1.这个run方法里面就是线程要做的业务‘
2.调用这个start才开始创建线程,只是实例化是不会创建的
创建一个实现Runnable接口的类
class MyThread implements Runnable{ @Override public void run() { System.out.println("我是线程"); } } public class Main { public static void main(String[] args){ Thread thread = new Thread(new MyThread()); thread.start(); } }
看这个和上一个方法的区别,上个方法直接实例化了MyThread而这个方法是实例化Thread然后把MyThread作为参数
匿名内部类
public class Main { public static void main(String[] args){ Thread thread = new Thread() { @Override public void run() { System.out.println("我是线程"); } }; thread.start(); } }
内部类的方式实现方法一
实现Runnable的匿名内部类作为参数
public class Main { public static void main(String[] args){ Thread thread = new Thread(new Runnable() { @Override public void run() { System.out.println("我是线程"); } }); thread.start(); } }
用内部类的形式完成了方法二
Lamada
public class Main { public static void main(String[] args){ Thread thread = new Thread(()->{ System.out.println("太方便拉!"); }); thread.start(); } }
推荐使用实现Runnable的接口方法,实现了代码之间的解耦合,你看如果用方法一的话,只能用实例化MyThread的方式创建线程,也就是说必须要把所有线程的业务代码都塞在这一个类中,而重写Runnable在创建线程的时候可以用多种实现Runnable的接口的类作为参数,不一定要把代码塞在一个类里面
Thread的三种构造方法
无参数的
Thread() 就像方法二(匿名内部类实现)
以Runnable实例为参数
Thread(new Runnable())
字符串参数
Thread(String name) 用来重命名线程
Thread的重要方法
start()
创建线程 如果没有start线程就不会创建
run()
描述线程的业务
interrupt()
中断线程
join()
等待线程
加入在t2中调用t1.join() 就是说在t1完成后 才继续执行t2
getstate()
获取线程状态
new:
此时
java
只把线程业务写好,创建了线程对象,但没有执行start
方法,也就是还没有创建对应的线程!runnable:
对应已经调用了start方法的状态(分为正在工作 可工作 即将工作)
terminate:
对应着线程以及结束,但是这个线程实例还在,(要不也调用不了方法不是)
blocked
正在等待锁,后面synchronized细说
waiting(无线等待)
一个正在无限期等待另一个线程执行一个唤醒动作的线程(wait造成的)
time-waiting(定时等待)
一个正在限时等待另一个线程执行一个唤醒动作的线程(sleep或者获得锁对象后wait)
Thread.sleep()/sleep()
Thread.sleep()静态方法,当前线程进入休眠状态,里面可以输入参数(单位ms)
sleep() 比如t1.sleep() 线程t1休眠 里面可以输入参数(单位ms)
Thread.interrupted()
静态方法,测试线程是否中断
Thread.currentThread()
静态方法,返回当前线程实例
关于线程中断
线程中断 就是结束当前线程,手动中断线程有两种方法
1.手动设置标志位
public class Main { public static void main(String[] args){ boolean isQuit = false; Thread thread = new Thread(()->{ if(!isQuit) { System.out.println("yes!!!"); } }); thread.start(); } }
2.用interrupt()的方式
用interrupt要注意 如果是sleep状态的线程调用interrupt会报异常