当前位置: 首页 > ds >正文

Java多线程随笔

什么是进程?

系统进行资源分配和调度的基本单位。

什么是线程?

cpu调度的最小单位。

什么是多线程?

允许多个线程在同一个程序中并发执行。

多线程作用?

提高程序执行效率。

多线程实现的三种方式

1.通过继承Thread类,重写run()方法实现

public class ThreadDemo {public static void main(String args[]){MyThread myThread1 = new MyThread();myThread1.setName("Thread-1");MyThread myThread2 = new MyThread();myThread2.setName("Thread-2");myThread1.start();myThread2.start();}
}
class MyThread extends   Thread{public void say(){for(int i=0;i<100;i++){System.out.println(getName()+": "+i);}}public void run(){say();}
}

可通过getName()获取当前线程名。

2.通过实现Runnable接口,再创建Thread类执行其run()方法。

public class RunnableDemo {public static void main(String[] args) {People people1 = new People();People people2 = new People();Thread thread1 = new Thread(people1);Thread thread2 = new Thread(people2);thread1.setName("people1");thread2.setName("people2");thread1.start();thread2.start();}
}
class People implements Runnable{private void say(){for(int i=0;i<100;i++){System.out.println(Thread.currentThread().getName() + " say hello"+i);}}public void run() {say();}
}

因为没有继承Thread类,所以不能直接调用getName(),

而是通过获取当前执行程序的线程Thread.currentThread(),再获取线程名。

3.通过Callable接口和Future接口实现

Callable泛型为结果的类型,即call方法返回类型。

import java.util.concurrent.Callable;public class MyCallable implements Callable<Integer> {public Integer call() throws Exception {return 10;}
}

创建FutureTask对象中泛型也为返回值类型,通过Thread代理执行后,通过get()方法获取返回结果

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;public class CallableDemo {public static void main(String[] args) throws ExecutionException, InterruptedException {MyCallable mc = new MyCallable();FutureTask<Integer> ft = new FutureTask<>(mc);new Thread(ft).start();System.out.println(ft.get());}
}

什么是守护线程?

所有非守护线程执行完成后,守护线程即使未执行完成,也会结束。

场景

比如一个聊天框,现在正在传输文件,聊天框是一个线程,传输文件是一个线程,当关闭聊天框后,传输文件线程也会关闭。

同步代码块

synchronized 同步代码块中代码是轮流执行,执行中加锁,其他线程无法进入。

锁对象唯一,一般是该类的字节码文件(xx.class)

lock锁

类似同步代码块

lock.lock()上锁。

lock.unlock()解锁。

建议将解锁放在finally代码块中,防止中间代码break等跳过解锁。

package lockpackage;import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;public class MyThread implements Runnable{int count =0;Lock lock = new ReentrantLock();@Overridepublic void run() {while(true){lock.lock();try{if(count == 100) break;count++;Thread.sleep(10);System.out.println(Thread.currentThread().getName()+"正在售卖第"+count+"张票");}catch( InterruptedException e){e.printStackTrace();}finally {lock.unlock();}}}
}

等待和唤醒

wait():线程等待,直到其他线程唤醒

notify():随机唤醒线程

notifyAll():唤醒所有等待线程

案例

package threadDemo;public class Cook implements Runnable{@Overridepublic void run() {while(true){if(Desk.count == 0){break;}else{synchronized (Desk.lock){if(Desk.eatFlag == 1){try {Desk.lock.wait();} catch (InterruptedException e) {e.printStackTrace();}}else{System.out.println("厨师正在制作食物。。。");Desk.eatFlag = 1;Desk.lock.notifyAll();}}}}}
}
package threadDemo;public class Customer implements Runnable {@Overridepublic void run() {while (true){if(Desk.count == 0){break;}else{synchronized (Desk.lock){if(Desk.eatFlag == 0){try {Desk.lock.wait();} catch (InterruptedException e) {e.printStackTrace();}}else{Desk.count--;Desk.eatFlag = 0;System.out.println("顾客还能吃第"+Desk.count+"碗面条");Desk.lock.notifyAll();}}}}}
}
package threadDemo;public class Desk {//能吃多少碗饭public static int count = 10;//锁对象public static Object lock = new Object();//吃的状态 0:未吃 1:已吃public static int eatFlag = 0;
}
package threadDemo;public class Main {public static void main(String[] args) {Cook cook = new Cook();Customer customer = new Customer();new Thread(cook).start();new Thread(customer).start();}
}

ArrayBlockingQueue

阻塞队列

put:放入数据(如果队列放满了等待)
take:取出数据(两方法都加了锁)(如果数据队列为空则等待)ArrayBlockingQueue<String> queue = new ArrayBlockingQueue<>(1);//队列长度

线程池

ExecutorService executorService = Executors.newFixedThreadPool(3);//创建线程数为3的线程池
ExecutorService cachedThreadPool = Executors.newCachedThreadPool();//线程池数无上限executorService.submit(执行任务);//调用该对象run方法
executorService.shutdown(); //关闭线程池//七大核心public class Main {public static void main(String[] args) {ThreadPoolExecutor executor = new ThreadPoolExecutor(3, //核心线程数5, //最大线程数60, //临时线程存活时间TimeUnit.SECONDS, //时间单位new ArrayBlockingQueue<>(2), //阻塞队列Executors.defaultThreadFactory(), //线程工厂new ThreadPoolExecutor.AbortPolicy() //线程池饱和策略);executor.submit(); //提交任务}
}

http://www.xdnf.cn/news/7864.html

相关文章:

  • 03-Web后端基础(Maven基础)
  • C#实现自己的MCP Client
  • CSS、SCSS 和 SASS 的语法差异
  • 将VMware上的虚拟机和当前电脑上的Wifi网卡处在同一个局域网下,实现同一个局域网下实现共享
  • 07SpringMVC底层形象解析
  • 2022年下半年信息系统项目管理师——综合知识真题及答案(5)
  • 使用Vite创建一个动态网页的前端项目
  • 1.0 Epson数据类型以及函数的传值与传址
  • 微信小程序中,解决lottie动画在真机不显示的问题
  • CSDN gitcode代码推送
  • 博主总结框架
  • RISC-V 开发板 MUSE Pi Pro CSI测试,一把点亮ov5647摄像头
  • R语言学习--Day05--绘图技巧
  • .NET外挂系列:5. harmony 中补丁参数的有趣玩法(下)
  • 野火鲁班猫(arrch64架构debian)从零实现用MobileFaceNet算法进行实时人脸识别(四)安装RKNN Toolkit Lite2
  • IP地址详解
  • vue调后台接口
  • 【5.19-5.26学习周报】
  • RPA浪潮来袭,职业竞争的新风口已至?
  • HOT100(二叉树)
  • 大语言模型 16 - Manus 超强智能体 Prompt分析 原理分析 包含工具列表分析
  • Python数据库编程案例
  • 2022CCPC吉林省赛长春邀请赛 Java 做题记录
  • 软考软件评测师—— 操作系统综合知识
  • RedissonClient主要功能概述
  • 黑马点评相关知识总结
  • 大模型会话窗口为什么对最新和最久记忆表现较好
  • 13 分钟讲解所有知名 Python 库/模块
  • 命名常量集合接口INamedConstantCollection<T>实现
  • 顶级流媒体服务商 Spotify 2025.04 故障复盘报告,吃他人的堑长自己的智