犀牛云建设网站,响应式网页设计实例,模板网站报价明细,杭州网站搜索目录
二、多线程代码
1.继承Thread类
2.实现Runnable接口 3.匿名内部类
3.1 创建Thread⼦类对象
3.2 创建Runnable⼦类对象
4.lambda表达式#xff08;推荐#xff09; 小结#xff1a;
#x1f525;面试题#xff1a;Java中创建线程都有哪些写法 二、多线程代码
…目录
二、多线程代码
1.继承Thread类
2.实现Runnable接口 3.匿名内部类
3.1 创建Thread⼦类对象
3.2 创建Runnable⼦类对象
4.lambda表达式推荐 小结
面试题Java中创建线程都有哪些写法 二、多线程代码
1.继承Thread类
package thread;class MyThread extends Thread {Overridepublic void run() {//这里写的代码就是该线程要完成的工作while (true) {System.out.println(hello thread);try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}}
}public class Demo1 {public static void main(String[] args) throws InterruptedException {Thread t new MyThread();//t.start();//没有创建出新的线程就是在主线程中执行run中的循环打印(就是单线程了串行执行t.run();while (true) {System.out.println(hello main);t.sleep(1000);}}
}上述代码中其实有两个线程一个t线程一个main线程主线程JVM进程启动的时候自己创建的线程重写Thread方法中的run方法描述线程需要完成的工作 只是定义好把这个方法的调用交给系统/其他的库/其他框架调用回调函数sleep方法让当前线程主动进入“阻塞”状态主动放弃在CPU上的执行时间到了才会解除重新被调度到CPU上执行start方法调用操作系统提供创建线程的API在内核中创建对应的PCB并且把PCB加入到链表中进一步的系统调度到这个线程之后就会执行上述run方法的逻辑Q1如果开发中发现你负责的服务器程序消耗CPU资源超出预期你如何排查 首先确认是哪个线程消耗的CPU比较高 进一步排查线程中是否有类似的“非常快速的”循环 确认是否这里的循环一个这么快 应该的话就可以升级更好的CPU 如果不应该说明需要在循环中引入一些等待操作上述代码结果顺序是不确定的 多线程的调度是无序的即抢占式执行任何一个线程 在执行任何一个代码的时候都可能被其他线程抢占CPU资源 2.实现Runnable接口
package thread;class MyRunnable implements Runnable {Overridepublic void run() {while (true) {System.out.println(hello thread);try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}}
}public class Demo2 {public static void main(String[] args) {Thread t new Thread(new MyRunnable());t.start();while (true) {System.out.println(hello main);try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}}
}Runnable的作用是描述一个“任务”表示“可执行的”和继承Thread类创建线程比较 一是Thread自己记录要干啥 二是Runnable记录要干啥Thread负责执行 好处解耦合把任务和线程拆分开把这样的任务给其他地方执行 3.匿名内部类
3.1 创建Thread⼦类对象
package thread;public class Demo3 {public static void main(String[] args) throws InterruptedException {Thread t new Thread() {Overridepublic void run() {while(true) {System.out.println(hello thread);try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}}};t.start();while (true) {System.out.println(hello main);Thread.sleep(1000);}}
}过程 创建一个Thread子类 同时创建一个该子类的实例 但是对于匿名内部类来说只能创建这一个实例因为拿不到名字 子类内部重新父类的run方法好处简单 3.2 创建Runnable⼦类对象
package thread;public class Demo4 {public static void main(String[] args) throws InterruptedException {Thread t new Thread(new Runnable() {Overridepublic void run() {while (true) {System.out.println(hello thread);try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}}});t.start();while (true) {System.out.println(hello main);Thread.sleep(1000);}}
}过程和3.1代码一样区别此处的匿名内部类只是针对Runnable和Thread没有关系 只是把Runnable的实例作为参数传入Thread的构造方法中Q1为什么在main方法中处理sleep异常有两种选择而线程run中的sleep方法只有一种 main方法可以 throws try catch 线程中的run方法 只能try catch 因为父类run中没有抛出异常由于重写要求方法签名是一样的的也无法抛出异常 throws其实是方法签名的一部分方法名字方法的参数列表【不包含返回值和pubic/private】声明抛出的异常 4.lambda表达式推荐
package thread;public class Demo5 {public static void main(String[] args) throws InterruptedException {Thread t new Thread(() - {while (true) {System.out.println(hello thread);try {Thread.sleep(10000);} catch (InterruptedException e) {throw new RuntimeException(e);}}});t.start();while (true) {System.out.println(hello main);Thread.sleep(1000);}}
}本质就是一个”匿名函数“一次性函数用完就丢 小结
5种方法都是要把线程的任务内容表示出来通过Thread的start来创建/启动系统中的线程 Thread对象和操作系统中的线程是一一对应的关系 面试题Java中创建线程都有哪些写法 继承Thread类实现Runnable接口匿名内部类 创建Thread子类 创建Runnable子类lambda表达式实现Callable接口TODO使用线程池TODO