多线程知识点
一、创建新执行线程有两种方法:
① 一种方法是将类声明为 Thread 的子类。该子类应重写 Thread 类的 run 方法。创建对象,开启线程使用start关键字
public static void main(String[] args) { //创建线程对象 MyThread mt=new MyThread(); //开启线程 mt.start(); // for(int i=0;i<100;i++){ System.out.println(Thread.currentThread().getName()+":"+i); } }
public class MyThread extends Thread { //描述线程任务 public void run(){ //这个地方必须是run关键字 使用别的关键字会报错 for(int i=0;i<100;i++){ System.out.println(Thread.currentThread().getName()+":"+i); } } }
还可以用线程匿名内部类来实现;
public static void main(String[] args) { //继承thread类 Thread th = new Thread() { public void run() { for(int i=0;i<20;i++){ System.out.println(Thread.currentThread().getName()+":"+i); } } }; //开启线程 th.start(); }
②另一种方法是声明一个实现 Runnable 接口的类。该类然后实现 run 方法。然后创建Runnable的子类对象,传入到某个线程的构造方法中,开启线程。
public class MyRunnable implements Runnable{ //继承runnable public void run() { for(int i=0;i<100;i++){ System.out.println(Thread.currentThread().getName()+":"+i); } } }
public static void main(String[] args) { // 创建线程任务 MyRunnable mr=new MyRunnable(); //创建线程对象并明确线程任务 Thread th=new Thread(mr); //开启线程 th.start(); //描述主线程任务 for(int i=0;i<100;i++){ System.out.println(Thread.currentThread().getName()+":"+i); } }
同样可以用线程匿名内部类来实现;
public static void main(String[] args) { Runnable my = new Runnable() { public void run() { for (int i = 0; i < 10; i++) { System.out.println(Thread.currentThread().getName() + ":" + i); } } }; Thread th = new Thread(my); th.start(); }
二、线程池
线程池主要用来解决线程生命周期开销问题和资源不足问题;
使用线程池关键字 :Runnable 接口 和 Callable接口
以Callable接口为例介绍;
public class MyCallable implements Callable<String>{ public String call() throws Exception { // return "abc"; } }
public static void main(String[] args) { //创建线程任务对象 MyRunnaber02 mr=new MyRunnaber02(); //获取线程池对象 ExecutorService es=Executors.newFixedThreadPool(2); //调用mr线程任务 es.submit(mr); es.submit(mr); //销毁线程池 es.shutdown(); }
练习:异步计算,2个线程,1个计算10的阶乘,一个计算20的阶乘并返回;
public class JiSuan implements Callable<Long>{ 由于20的阶乘比较大 使用integer泛型会溢出 private int num; public JiSuan(int num){ this.num=num; } public Long call() throws Exception { long sum=1; for(int i=1;i<=num;i++){ sum=sum*i; } return (long) sum; } }
public static void main(String[] args) throws InterruptedException, ExecutionException { JiSuan js1=new JiSuan(10); JiSuan js2=new JiSuan(20); //创建线程池 ExecutorService ex=Executors.newFixedThreadPool(2); //执行任务 Future<Long> f1=ex.submit(js1); Future<Long> f2=ex.submit(js2); System.out.println(f1.get()+"...."+f2.get()); }
此 练习充分运用了线程池的原理;可能会有更简单方法 欢迎各位大神指点和评论;
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· Vue3状态管理终极指南:Pinia保姆级教程