前言
兄弟们有什么建议或者面试题都拿出来我做个总结大家一起进步拿到高薪!!!
1、线程的创建方式?
线程简介(顺便区分一下进程):
进程和线程算是操作系统内两个很基本、很重要的概念了,进程是操作系统中进行保护和资源分配的基本单位,操作系统分配资源以进程为基本单位。线程是进程的组成部分,它代表了一条顺序的执行流。
1、 继承Thread类,作为线程对象存在(继承Thread对象)
public class MyThread extends Thread {}
//main方法
MyThread t=new MyThread();
//主方法中启动方法
t.start();
2、实现runnable接口,作为线程任务存在
public class MyRunnable implements Runnable{}
// main中创建MyRunnable对象
MyRunnable mr = new MyRunnable() ;
// 创建Thread对象
Thread t1 = new Thread(mr) ;
// 调用start方法启动线程
t1.start();
3、创建带返回值的线程(实现Callable接口):这个需要注意的是此接口是带泛型的,同时有返回值、抛异常的方式
public class MyCallable implements Callable<String>{}
public static void main(String[] args) throws ExecutionException, InterruptedException {
// 创建MyCallable对象
MyCallable mc = new MyCallable() ;
// 创建F
FutureTask<String> ft = new FutureTask<String>(mc) ;
// 创建Thread对象
Thread t1 = new Thread(ft) ;
// 调用start方法启动线程
t1.start();
// 调用ft的get方法获取执行结果
String result = ft.get();
// 输出
System.out.println(result);
}
4、线程池创建线程
public class MyRunnable implements Runnable{}
//主方法
public static void main(String[] args) {
// 创建线程池对象
ExecutorService threadPool = Executors.newFixedThreadPool(3);
threadPool.submit(new MyRunnable()) ;
2、线程有哪些基本状态?
源码在java.lang.Thread.State枚举类中
新建状态(NEW):一个尚未启动的线程状态。新的刚创建没启动没有使用方法 只new出来对象。
就绪状态(RUNNABLE):启动 调用start方法了,JVM进程创建线程,但是没有立即执行,等待CPU命令,这个状态叫RUNNABLE。(操作系统隐藏 Java 虚拟机中的 READY 和 RUNNING 状态,它只能看到 RUNNABLE 状态,所以 Java 系统一般将这两个状态统称为 RUNNABLE(运行中) 状态 。)
运行状态(Running):如果处于就绪状态的线程获得了 CPU,开始执行 run()方法的线程执行体,则该线程处于运行状态。
阻塞状态(Blocked):阻塞状态是指线程因为某种原因放弃了 cpu 使用权,停止执行线程,这时候称为阻塞状态(当线程持有锁时,该线程将变成Runnable状态)。
阻塞状态又分为三种:
1、等待阻塞(WAITING):调用wait(),join()方法后JVM把线程放入等待队列中。
2、同步阻塞:运行的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则 JVM 会把该线 程放入锁池中。
3、其他阻塞(TIMED_WAITING):一个在限定时间内等待的线程的状态。也称之为限时等待状态。造成线程限时等待状态的原因有三种,分别是Thread.sleep(long)Object.wait(long)、join(long)。
线程死亡(DEAD/TERMINATED ):一个完全运行完成的线程的状态。也称之为终止状态、结束状态
3、如何停止一个线程
1、使用stop方法强制退出:使用stop()方法强制终止线程
启动类中 直接使用 .stop();方法 暴力 ;
2、使用interrupt方法中断线程,该方法只是告诉线程要终止,但最终何时终止取决于计算机;
启动类 中直接 使用 .interrupt();方法 ;随机 停止
3、设置标志位:使用设置退出标志,使线程正常退出,也就是当run方法完成后线程终止; 线程类 中 定义volatile Boolean i = true;
启动类中想停止 把 i 改为 false
4、有三个线程T1,T2,T3,如何保证顺序执行?
第一种方式:顺序在线程中创建实例 .sleep()(最容易想到的办法)
Thread.sleep(100);
Thread.sleep(200);
Thread.sleep(300);
第二种方式:单个线程池 顺序放入执行队列中
ExecutorService executor = Executors.newSingleThreadExecutor();
executor.submit(t3);
executor.submit(t2);
executor.submit(t1);
executor.shutdown();
第三种方式(最优):运用线程的 join 方法来实现
public static void main(String[] args) {
// 创建线程对象
Thread t1 = new Thread(() -> {
System.out.println("t1");
}) ;
Thread t2 = new Thread(() -> {
try {
t1.join(); // 加入线程t1,只有t1线程执行完毕以后,再次执行该线程
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("t2");
}) ;
Thread t3 = new Thread(() -> {
try {
t2.join(); // 加入线程t2,只有t2线程执行完毕以后,再次执行该线程
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("t3");
}) ;
// 启动线程
t1.start();
t2.start();
t3.start();
}
5、在线程中你怎么处理不可控制异常?
首先在java中有两种异常:(线程的问题应该由线程自己来解决,而不要委托到外部)
1、非运行时异常(Checked Exception):这种异常必须在方法声明的throws语句指定,或者在方法体内捕获。
2、运行时异常(Unchecked Exception):这种异常不必在方法声明中指定,也不需要在方法体中捕获。
run()方法不支持throws语句,所以当线程对象的run()方法抛出非运行异常时,我们必须捕获并且处理它们。如果没有被捕获处理,则会一直向上抛,最后出现在控制台。
java提供给我们一种在线程对象里捕获和处理运行时异常的一种机制。实现用来处理运行时异常的类,这个类实现UncaughtExceptionHandler接口并且实现这个接口的
//实现异常处理类
class ThreadExceptionHandler implements Thread.UncaughtExceptionHandler {
@Override
public void uncaughtException(Thread t, Throwable e) {
System.out.println(t.getId() + "---" + t.getState());
e.printStackTrace();
}
// main方法中线程对象直接设置运行期异常的处理器类
t.setUncaughtExceptionHandler(new ThreadExceptionHandler());