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

Java进阶 多线程

多线程

  • 多线程创建方式一:继承Thread类
    • 编码简单
    • 线程对象
public class Test1 {public static void main(String[] args) {//创建线程,继承Thread类来实现Thread t1=new MyThread();t1.start();//启动要调用start();for (int i = 0; i < 5; i++) {System.out.println("主线程输出"+i);}}
}
//定义一个子类继承Thread类,成为一个线程类
class MyThread extends Thread {//重写Thread类的run方法@Overridepublic void run() {for (int i = 0; i < 5; i++) {System.out.println("子线程输出"+i);}}
}
  • 多线程创建方式二:实现Runnable接口
    • 线程任务对象
public class Test1 {public static void main(String[] args) {//创建线程任务类的对象代表一个线程任务Runnable r=new MyRunnable();//把线程任务对象交给一个线程对象来处理Thread t=new Thread(r);t.start();//启动线程}
}
//定义一个线程任务类实现Runnable接口
class MyRunnable implements Runnable {//重写run方法,设置线程任务@Overridepublic void run() {for (int i = 0; i < 10; i++) {System.out.println("子线程输出"+i);}}
}
  • 多线程创建方式三:实现Callable接口,利用FutureTask类(Runnable的实现类)
    • 可以返回线程执行完毕后的结果
public class Test1 {public static void main(String[] args) {//创建Callable接口的实现类对象Callable<String> c1=new MyRunnable(100);//把Callable对象封装成一个真正的线程任务对象FutureTask对象FutureTask<String> f1=new FutureTask<>(c1);//把线程任务对象交给一个线程对象来处理new Thread(f1).start();}
}//定义一个实现类实现Callable接口
class MyRunnable implements Callable<String> {private int n;public MyRunnable(int n) {this.n = n;}//实现call方法,定义线程执行体@Overridepublic String call() throws Exception {int sum = 0;for (int i = 0; i < n; i++) {System.out.println(i);sum += i;}return "子线程计算出的结果是" + sum;}
}

线程同步:

  • 同步代码块
public class Account{private String cardId;private double money;public void drawMoney(double money) {//获取线程名字来拿到谁来取钱String name =Thread.currentThread().getName();//加锁,锁名为当前卡synchronized (this) {//对于实例方法,使用this作为锁对象,对于静态方法,使用字节码(类名.class)作为锁对象//判断余额是否足够if(this.money>=money){System.out.println(name+"取钱成功");this.money-=money;//更新余额System.out.println("取钱后余额为"+this.money);}else{System.out.println("余额不足");}}}
}
  • 同步方法
public class Account{private String cardId;private double money;//把访问共享资源的核心方法加锁public synchronized void drawMoney(double money) {//获取线程名字来拿到谁来取钱String name =Thread.currentThread().getName();//判断余额是否足够if(this.money>=money){System.out.println(name+"取钱成功");this.money-=money;//更新余额System.out.println("取钱后余额为"+this.money);}else{System.out.println("余额不足");}}
}
  • Lock锁
public class Account{private String cardId;private double money;private final Lock lock = new ReentrantLock();//定义锁,并且不让锁被修改public void drawMoney(double money) {//获取线程名字来拿到谁来取钱String name =Thread.currentThread().getName();lock.lock();//上锁try {//判断余额是否足够if(this.money>=money){System.out.println(name+"取钱成功");this.money-=money;//更新余额System.out.println("取钱后余额为"+this.money);}else{System.out.println("余额不足");}} finally {lock.unlock();//解锁}}
}

线程池

  • 可以复用线程的技术

  • 线程池接口:ExecutorService

  • 方式一:使用ExecutorService的实现类ThreadPoolExecutor自创建一个线程池对象。

  • 方式二:使用Executors(线程池的工具类)调用方法返回不同特点的线程池对象。

进程

  • 线程是属于进程的,一个进程中可以同时运行多个线程
  • 进程中的多个线程是并发和并行同时执行的
  • 并发:
    • 给人感觉这些线程在同时执行
  • 并行:
    • 在同一时刻上,同时有多个线程在被CPU调度执行

抢红包游戏

屏幕截图 2025-12-02 150147

//测试类
import java.util.ArrayList;
import java.util.List;
import java.util.Random;public class ThreadTest {public static void main(String[] args) {//分析:100个员工实际上相当于100个线程,来竞争200个红包List<Integer> redPacket = new ArrayList<>();//创建红包//定义线程类,创建100个线程,竞争同一集合for (int i = 1; i <= 100; i++) {Thread thread =new GetRedPacket(redPacket,"人"+i);thread.start();}}//准备200个红包返回,放到List集合中去返回public static List<Integer> getRedPacket(){//小红包[1-30]元之间,占比为80%,大红包[31-100]元占比为20%List<Integer> redPacket = new ArrayList<>();//随机产生数字Random random = new Random();//小红包为160个for (int i = 1; i <= 160; i++) {redPacket.add(random.nextInt(29)+1);//随机产生1-30大小的数字}for (int i = 1; i <= 40; i++) {redPacket.add(random.nextInt(70)+31);//随机产生31-100大小的数字}return redPacket;}
}
//线程类import java.util.List;public class GetRedPacket extends Thread{private List<Integer> redPacket;public GetRedPacket(List<Integer> redPacket, String name) {super(name);this.redPacket = redPacket;}@Overridepublic void run() {String name=Thread.currentThread().getName();//100个人来抢红包(redPacket集合)中的钱while (true) {//每个人都可以不断的抢红包synchronized (redPacket){//加锁if(redPacket.size()==0) {break;//当红包抢完了,就返回}//随机一个索引得到红包int index=(int)(Math.random()*redPacket.size());Integer money=redPacket.remove(index);//抢到后就移除这个红包System.out.println(name+"抢到了"+money+"元");if(redPacket.size()==0) {System.out.println("活动结束!");break;//当红包抢完了,就返回}}}}
}
http://www.jsqmd.com/news/58741/

相关文章:

  • Java进阶网络编程,UDP,TCP通信
  • CCPC郑州站 笨蛋题 II
  • IDEA标签窗口好行显示 类注释和方法注释
  • LabVIEW用直线边缘检测实现液位测量 - 教程
  • HEK293细胞:为什么它是重组蛋白表达的黄金标准?
  • kettle从入门到精通 第111课 ETL之kettle webspoon7的docker部署详细教程
  • 树莓派Docker部署AdGuard Home
  • 人工智能发展史简述
  • 第四天敏捷冲刺
  • qy_蓝桥杯编程系列_编程17 好数
  • 读书笔记 XILINX ug1137-Zynq UltraScale+ MPSoC Software Developer Guide 软件开发者指南 Chapter1Chapter2
  • static相关
  • 74_基于深度学习的垃圾桶垃圾溢出检测体系(yolo11、yolov8、yolov5+UI界面+Python项目源码+模型+标注好的数据集)
  • Java创建对象完整流程详解
  • PQ v.Next Beta计划与估计
  • re笔记5
  • 北京陪诊公司陪诊师排行
  • 北京陪诊公司排行:专业服务破解就医难题,三甲机构树立行业标杆
  • 【RAG安全】Pirates of the RAG: Adaptively Attacking LLMs to Leak Knowledge Bases - 指南
  • 20232319 2025-2026-1 《网络与系统攻防技术》实验八实验报告
  • 北京上门收酒茅台五粮液洋酒老酒名酒
  • 北京上门收酒茅台五粮液洋酒老酒名酒董酒习酒
  • this view is read-only (IntelliJ IDEA) - 详解
  • 构建高可靠 OpenEuler 运维体系:从虚拟化部署到 Systemd 自动化核心实践 - 教程
  • 内存管理-55-工具-page_types - Hello
  • 2025 年黑猪批发基地品牌推荐排行榜,黑金刚黑猪批发,国寿黑猪批发,杜洛克黑猪批发,沂蒙黑猪批发,太湖原种黑猪批发,三元仔猪黑猪批发,长白仔猪黑猪养殖,黑猪繁育,黑猪仔猪批发,原种黑猪批发基地推荐
  • 2025年必收藏的8款AI论文生成神器!高效写作轻松搞定
  • FWT 学习笔记
  • 补发读后感
  • 北京上门收酒的公司