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

Java Day13 多线程

多线程

  • 1、 方式一 Thread
  • 2、实现Runnable接口
  • 3、实现 Callable接口
  • 4、与线程有关的操作方法
  • 5、线程安全问题
    • 5.1 取钱案例
    • 5.2 线程同步
      • 5.2.1 同步代码块
      • 5.2.2 同步方法
      • 5.2.3 Lock锁
  • 6、线程池
    • 6.2 创建线程池
      • 6.2.1 使用ExecutorService创建
      • 新任务策略
      • 6.2.2 使用Executors工具类创建
      • 核心线程数量问题
  • 7、并发、并行,线程生命周期
  • 7、乐观锁、悲观锁

1、 方式一 Thread

继承 Thread类
优点:编码简单
缺点:java是单继承,继承了一个类,就不能继承其他,可拓展性不强。

注意:
①子线程一定要调用start方法,而不是run方法,调用run方法,还是相当于在main线程中创建了一个实例对象,在运行她的方法, 而已,是单线程的。调用strat方法,虽然底层还是调用run方法,但是他会告诉cpu说我们另外启动了一个线程。
②子线程启动一定要在主线程任务之前。
③每次执行的结果会不同。

package com.cky.file;public class MyThread extends  Thread{@Overridepublic void run() {for (int i = 0; i <5 ; i++) {System.out.println("子线程"+i);}}
}
package com.cky.file;public class Endecode {public static void main(String[] args) throws Exception {Thread thread=new MyThread();thread.start();for (int i = 0; i <5 ; i++) {System.out.println("主线程"+i);}}}

2、实现Runnable接口

在这里插入图片描述

package com.cky.file;public class MyRunnable implements  Runnable{@Overridepublic void run() {for (int i = 0; i <5 ; i++) {System.out.println("子线程"+i);}}
}
package com.cky.file;public class Endecode {public static void main(String[] args) throws Exception {//创建一个任务对象MyRunnable myRunnable=new MyRunnable();//调用线程类的start方法new Thread(myRunnable).start();//匿名内部类Runnable runnable = new Runnable() {@Overridepublic void run() {for (int i = 0; i < 5; i++) {System.out.println("子线程" + i);}}};new Thread(runnable).start();//简化形式1new Thread(new Runnable() {@Overridepublic void run() {for (int i = 0; i < 5; i++) {System.out.println("子线程" + i);}}}).start();//形式2new Thread(()-> {for (int i = 0; i < 5; i++) {System.out.println("子线程" + i);}}).start();for (int i = 0; i <5 ; i++) {System.out.println("主线程"+i);}}}

由于Runnable是一个函数式接口,匿名内部类可以使用lambda形式
在这里插入图片描述

3、实现 Callable接口

上边两种实现方法,都不能获得线程执行的结果并返回,方法3可以。
实现Callable接口 将该接口 封装为一个FutureTask 任务对象,最后在交给线程。
是一个泛型接口 这里String 是要返回的类型 可以定义为其他类型

package com.cky.file;import java.util.concurrent.Callable;public class MyCallable implements Callable<String> {private int n;public MyCallable(int n) {this.n = n;}@Overridepublic String call() throws Exception {int sum=0;for (int i = 1; i <= n; i++) {sum+=i;}return "1-"+n+"的和为:"+sum;}
}
package com.cky.file;import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;public class Endecode {public static void main(String[] args) throws Exception {//创建一个Callable对象Callable<String> callable=new MyCallable(100);//封装为一个FutureTask对象//FutureTask 是一个任务对象 实现了Runnable接口// 在执行完毕后 可以通过get方法获得执行结果FutureTask<String> f1 = new FutureTask<>(callable);//交给一个Thread对象new Thread(f1).start();//获得执行结果 注意:执行未结束 是不会取得结果的String s = f1.get();System.out.println(s);//1-100的和为:5050}}

在这里插入图片描述

4、与线程有关的操作方法

在这里插入图片描述

package com.cky.file;public class MyThread extends  Thread{public MyThread( String name){super(name);}@Overridepublic void run() {Thread t=Thread.currentThread();for (int i = 0; i <3 ; i++) {System.out.println(t.getName()+i);}}
}
package com.cky.file;import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;public class Endecode {public static void main(String[] args) throws Exception {MyThread myThread1=new MyThread("子线程1");//修改名字
//        myThread1.setName("子线程1");myThread1.start();MyThread myThread2=new MyThread("子线程2");
//        myThread2.setName("子线程2");myThread2.start();//哪个线程在执行 就是哪个线程Thread m = Thread.currentThread();String name = m.getName();System.out.println(name);for (int i = 0; i < 3; i++) {System.out.println(name+"线程"+i);}}}
package com.cky.file;import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;public class Endecode {public static void main(String[] args) throws Exception {
//当输出为3时 ,延缓5秒在运行for (int i = 0; i < 5; i++) {System.out.println(i);if(i==3)Thread.sleep(5000);}}}
package com.cky.file;import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;public class Endecode {public static void main(String[] args) throws Exception {MyThread myThread1=new MyThread("子线程1");myThread1.start();myThread1.join();//当前线程执行完毕 再往下进行MyThread myThread2=new MyThread("子线程2");myThread2.start();myThread2.join();Thread m = Thread.currentThread();String name = m.getName();System.out.println(name);for (int i = 0; i < 3; i++) {System.out.println(name+"线程"+i);}}}

子线程10
子线程11
子线程12
子线程20
子线程21
子线程22
main
main线程0
main线程1
main线程2

5、线程安全问题

5.1 取钱案例

造成线程安全问题原因:
同时存在多个线程,访问同一个共享资源,且都要修改该共享资源。
同时进入钱够的判断,造成线程 不安全

package com.cky.file;public class Account {private double money;public Account(double money) {this.money = money;}public double getMoney() {return money;}public void setMoney(double money) {this.money = money;}public void drawmoney(double money){String name=Thread.currentThread().getName();if (this.money>=money){System.out.println(name+"来取钱成功");this.money-=money;System.out.println(name+"取后,剩余:"+this.money);}else{System.out.println("钱不够");}}
}
package com.cky.file;public class MyThread extends  Thread{private Account account;public MyThread( Account account,String name){super(name);this.account=account;}@Overridepublic void run() {
//取钱account.drawmoney(10000);}}
package com.cky.file;import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;public class Endecode {public static void main(String[] args) {//创建一个共享账户Account account=new Account(10000);//两个线程MyThread myThread1=new MyThread(account,"小红");MyThread myThread2=new MyThread(account,"小明");myThread1.start();myThread2.start();}}

小红来取钱成功
小明来取钱成功
小红取后,剩余:0.0
小明取后,剩余:-10000.0

5.2 线程同步

解决线程安全问题的办法
在这里插入图片描述
在这里插入图片描述

5.2.1 同步代码块

  public void drawmoney(double money){String name=Thread.currentThread().getName();synchronized (this) {if (this.money>=money){System.out.println(name+"来取钱成功");this.money-=money;System.out.println(name+"取后,剩余:"+this.money);}else{System.out.println("钱不够");}}

实例方法 同步代码块 通常加this 代表当前资源 比如小红和小黑共享一个账户 小白和小亮共享一个账户,使用this 保证了 只锁住同一个账户 不被多个访问 但不会去锁住别人的账户。
如果是静态方法 每个类只有一份 只允许一个访问 通常用 类.class 来锁住所有,只允许一个人访问。

   public static void text(){synchronized (Account.class){}}

在这里插入图片描述

5.2.2 同步方法

 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(name + "取后,剩余:" + this.money);}else{System.out.println("钱不够");}}

在这里插入图片描述

5.2.3 Lock锁

在这里插入图片描述

package com.cky.file;import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;public class Account {private double money;//为每个账户创建一个锁对象private final Lock lock=new ReentrantLock();public Account(double money) {this.money = money;}public double getMoney() {return money;}public void setMoney(double money) {this.money = money;}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(name + "取后,剩余:" + this.money);}else{System.out.println("钱不够");}} catch (Exception e) {e.printStackTrace();}finally {//写在finally里,为了防止上边代码出错,导致没有解锁lock.unlock();}}
}

6、线程池

如果每一个线程都需要我们去新创建一个线程的话,就会耗资源并且耗时(创建线程是一件耗时的事)
此时就需要线程池,线程池可以复用线程,不用经常去创建线程。
并且线程池也可以确定任务队列中任务的个数。防止任务过多,导致内存溢出。
在这里插入图片描述

6.2 创建线程池

在这里插入图片描述

6.2.1 使用ExecutorService创建

在这里插入图片描述
在这里插入图片描述

package com.cky.file;public class MyRunnable implements  Runnable{private int n;public MyRunnable(int n) {this.n = n;}@Overridepublic void run()  {int sum=0;for (int i = 1; i <= n; i++) {sum+=i;}System.out.println(Thread.currentThread().getName()+"-1-"+n+"的和为:"+sum);try {Thread.sleep(100000);} catch (InterruptedException e) {e.printStackTrace();}}
}
package com.cky.file;import java.util.concurrent.*;public class Endecode {public static void main(String[] args) {//创建一个线程池对象/* int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,BlockingQueue<Runnable> workQueue,ThreadFactory threadFactory,RejectedExecutionHandler handler*/ExecutorService pool=new ThreadPoolExecutor(3,5,8,TimeUnit.SECONDS,new ArrayBlockingQueue<>(4),Executors.defaultThreadFactory(),new ThreadPoolExecutor.AbortPolicy());MyRunnable myRunnable=new MyRunnable(100);pool.execute(myRunnable);pool.execute(myRunnable);pool.execute(myRunnable);//开始往任务队列加pool.execute(myRunnable);pool.execute(myRunnable);pool.execute(myRunnable);pool.execute(myRunnable);//开始使用临时线程pool.execute(myRunnable);pool.execute(myRunnable);
//        开始使用任务队列满的措施pool.execute(myRunnable);}}
D:\JAVA\jdk-17.0.8\bin\java.exe "-javaagent:D:\SOftware\idea\IntelliJ IDEA 2021.3.2\lib\idea_rt.jar=49289:D:\SOftware\idea\IntelliJ IDEA 2021.3.2\bin" -Dfile.encoding=UTF-8 -classpath E:\java_code\project\out\production\hello-app;E:\java_code\project\hello-app\lib\dom4j-2.1.4.jar;E:\java_code\project\hello-app\lib\commons-io-2.15.1.jar com.cky.file.Endecode
Exception in thread "main" java.util.concurrent.RejectedExecutionException: Task java.util.concurrent.FutureTask@5b480cf9[Not completed, task = java.util.concurrent.Executors$RunnableAdapter@5f184fc6[Wrapped task = com.cky.file.MyRunnable@3feba861]] rejected from java.util.concurrent.ThreadPoolExecutor@6f496d9f[Running, pool size = 5, active threads = 5, queued tasks = 4, completed tasks = 0]at java.base/java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:2065)at java.base/java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:833)at java.base/java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1365)at java.base/java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:123)at com.cky.file.Endecode.main(Endecode.java:31)
pool-1-thread-1-1-100的和为:5050
pool-1-thread-2-1-100的和为:5050
pool-1-thread-5-1-100的和为:5050
pool-1-thread-3-1-100的和为:5050
pool-1-thread-4-1-100的和为:5050

//我们可以看到 使用了临时线程 并且使用了任务满时的策略。

新任务策略

在这里插入图片描述

package com.cky.file;import java.util.concurrent.Callable;public class MyCallable implements Callable<String> {private int n;public MyCallable(int n) {this.n = n;}@Overridepublic String call() throws Exception {int sum=0;for (int i = 1; i <= n; i++) {sum+=i;}return Thread.currentThread().getName()+"-1-"+n+"的和为:"+sum;}
}
package com.cky.file;import java.util.concurrent.*;public class Endecode {public static void main(String[] args) throws ExecutionException, InterruptedException {//创建一个线程池对象/* int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,BlockingQueue<Runnable> workQueue,ThreadFactory threadFactory,RejectedExecutionHandler handler*/ExecutorService pool=new ThreadPoolExecutor(3,5,8,TimeUnit.SECONDS,new ArrayBlockingQueue<>(4),Executors.defaultThreadFactory(),new ThreadPoolExecutor.AbortPolicy());Future<String> f1 = pool.submit(new MyCallable(100));Future<String> f2 = pool.submit(new MyCallable(200));Future<String> f3 =pool.submit(new MyCallable(300));Future<String> f4 =pool.submit(new MyCallable(400));System.out.println(f1.get());System.out.println(f2.get());System.out.println(f3.get());System.out.println(f4.get());}}

pool-1-thread-1-1-100的和为:5050
pool-1-thread-2-1-200的和为:20100
pool-1-thread-3-1-300的和为:45150
pool-1-thread-3-1-400的和为:80200

6.2.2 使用Executors工具类创建

在这里插入图片描述
在这里插入图片描述
创建单个线程池

   ExecutorService pool = Executors.newSingleThreadExecutor();pool.execute(new MyRunnable(100));

使用该种方式的风险
在这里插入图片描述

核心线程数量问题

如果时IO密集型 则一般配置 cpu数量*2
如果是计算密集型 则一般是 cpu数量+1

7、并发、并行,线程生命周期

在这里插入图片描述

并发
在这里插入图片描述
并行
在这里插入图片描述
在这里插入图片描述
生命周期
在这里插入图片描述
在这里插入图片描述

7、乐观锁、悲观锁

悲观锁:一上来就加锁,线程安全,性能较差。
乐观锁:不加锁,等到要开始出现线程安全问题时,才开始控制。

package com.cky.file;import java.util.concurrent.atomic.AtomicInteger;public class MyRunnable implements  Runnable{private AtomicInteger count=new AtomicInteger();@Overridepublic void run()  {for (int i = 0; i <100 ; i++) {System.out.println(Thread.currentThread().getName()+"count===>"+count.incrementAndGet());}}
}
package com.cky.file;import java.util.concurrent.*;public class Endecode {public static void main(String[] args) throws ExecutionException, InterruptedException {//乐观锁//100个线程 对一个变量 各加100次MyRunnable myRunnable=new MyRunnable();for (int i = 0; i <100 ; i++) {new Thread(myRunnable).start();}}}

相关文章:

Java Day13 多线程

多线程 1、 方式一 Thread2、实现Runnable接口3、实现 Callable接口4、与线程有关的操作方法5、线程安全问题5.1 取钱案例5.2 线程同步5.2.1 同步代码块5.2.2 同步方法5.2.3 Lock锁 6、线程池6.2 创建线程池6.2.1 使用ExecutorService创建新任务策略6.2.2 使用Executors工具类创…...

以太坊的演变:EIP、ERC 概念以及革命性的 ERC20、ERC721 和 ERC115 标准

文章目录 一、EIP——以太坊发展的基石1.1 什么是EIP&#xff1f;1.2 历史背景&#xff1a;前身的 BIP1.3 EIP的重要性1.4 流程&#xff1a;从提案到实施 二、进入 ERC——以太坊内的标准化协议2.1 解读 ERC&#xff1a;以太坊征求意见2.2 ERC 标准的诞生和意义 三、聚焦 ERC20…...

B003-springcloud alibaba 服务治理 nacos discovery ribbon feign

目录 服务治理服务治理介绍什么是服务治理相关方案 nacos实战入门搭建nacos环境安装nacos启动nacos访问nacos 将商品微服务注册进nacos将订单微服务注册进nacos订单服务通过nacos调用商品服务 实现服务调用的负载均衡什么是负载均衡代码实现负载均衡增加一个服务提供者自定义实…...

mac笔记本执行定时任务

1.mac本地设置一个定时任务每小时执行一次&#xff0c;在/Users/xxx/go/src/runing目录下执行命令&#xff1a;./git_push.sh 在macOS中&#xff0c;你可以使用crontab来设置定时任务。打开终端并执行以下步骤&#xff1a; 1.打开当前用户的crontab编辑器&#xff1a; crontab …...

解决linux系统网卡加载慢的问题

手上有块开发板&#xff0c;启动系统后&#xff0c;需要五六分钟后无线wifi网卡才能加载起来&#xff0c;网卡型号是qca9377。 第一步先确认是不是第一时间挂载到PCI总线上了&#xff0c;在ath10k_pci_probe函数中添加调试信息&#xff0c;另外查看/sys/bus/pci/drivers/ath10…...

Linux 命令或者一些工具

locale – 设置和显示程序运行的语言环境 locale -a | grep en_US.UTF-8.sudo locale-gen en_US.UTF-8sudo dpkg-reconfigure localesexpect 常用命令总结 expect命令spawnexpectsendexp_continuesend_userexit chrpath工具 chrpath 是一个用于修改可执行文件或共享库的运行…...

基于python的4s店客户管理系统

技术&#xff1a;pythonmysqlvue 一、背景 进入21世纪网络和计算机得到了飞速发展&#xff0c;并和生活进行了紧密的结合。目前&#xff0c;网络的运行速度以达到了千兆&#xff0c;覆盖范围更是深入到生活中的角角落落。这就促使管理系统的发展。网上办公可以实现远程处理事务…...

解决谷歌浏览器最新chrome94版本CORS跨域问题

项目场景&#xff1a; 谷歌浏览器升级到chrome94版本出现CORS跨域问题 问题描述 解决谷歌浏览器最新chrome94版本CORS跨域问题。 CORS跨域问题&#xff1a; 升级谷歌浏览器最新chrome94版本后&#xff0c;提示Access to XMLHttpRequest at ‘http://localhost:xxxx/api’ fro…...

JAVA 线程

目录 一、线程的定义 二、线程的实现 三、线程状态 程序并发执行多个任务 二、线程的实现 1、继承Thread类创建线程&#xff1a;通过继承Java的Thread类并重写其run()方法&#xff0c;可以创建一个新的线程。然后&#xff0c;通过调用线程的start()方法来启动线程&#xf…...

Rust 基于 await、async 的异步编程和纤程、协程的实现

一、Rust 的异步编程 Rust 通过 await、async 实现了其他语言中纤程、协程的机制。下面是一个使用async和await的Rust示例代码。这个示例展示了如何异步地读取文件内容。 首先&#xff0c;确保你的Cargo.toml文件包含了tokio库的依赖&#xff0c;如下&#xff1a; [dependen…...

【进阶五】Python实现SDVRP(需求拆分)常见求解算法——差分进化算法(DE)

基于python语言&#xff0c;采用经典差分进化算法&#xff08;DE&#xff09;对 需求拆分车辆路径规划问题&#xff08;SDVRP&#xff09; 进行求解。 目录 往期优质资源1. 适用场景2. 代码调整3. 求解结果4. 代码片段参考 往期优质资源 经过一年多的创作&#xff0c;目前已经成…...

什么是神经网络?

一、什么是神经网络&#xff1f; 神经网络又称人工神经网络&#xff0c;是一种基于人脑功能模型的计算架构&#xff0c;因此称之为“神经”。神经网络由一组称为“节点”的处理单元组成。这些节点相互传递数据&#xff0c;就像大脑中的神经元相互传递电脉冲一样。 神经网络在…...

基于Python的图形用户界面设计及应用

基于Python的图形用户界面设计及应用 摘要&#xff1a;随着信息技术的飞速发展&#xff0c;图形用户界面&#xff08;GUI&#xff09;已成为现代软件不可或缺的一部分。Python作为一种简洁、易读且功能强大的编程语言&#xff0c;提供了多种GUI开发工具包&#xff0c;如Tkinte…...

python网络爬虫实战教学——urllib的使用(1)

文章目录 专栏导读1、前言2、urllib的使用3、发送请求3.1 urlopen3.2 request 专栏导读 ✍ 作者简介&#xff1a;i阿极&#xff0c;CSDN 数据分析领域优质创作者&#xff0c;专注于分享python数据分析领域知识。 ✍ 本文录入于《python网络爬虫实战教学》&#xff0c;本专栏针对…...

简述归并排序

归并排序 特点&#xff1a; 高效稳定时间复杂度最佳/平均/最差&#xff1a; O(N log N) 递归算法有专门的公式来计算时间复杂度 空间复杂度 O(N) 因为开辟了临时的tem_arr数组 一个静态的演示图(from leetcode) 一个动态的演示图 合并实现使用merge函数 inline void merge(v…...

HTML实现卷轴动画完整源码附注释

动画效果截图 页面的html结构代码 <!DOCTYPE html> <html> <head lang=...

sh: 1: dtc: not found

报错&#xff1a; bl31.bin size: 41632 u-boot-nodtb.bin size: 815816 ai_robot.dtb size: 30552 ./mkimage_uboot -E -p 0x3000 -f u-boot-ai-robot.its u-boot-ai-robot.itb sh: 1: dtc: not found ./mkimage_uboot: Cant open u-boot-ai-robot.itb.tmp: No such file …...

laravel 表单验证的 exists、unique 去除软删除字段的校验

use Illuminate\Validation\Rule; exists 去除软删除字段的校验 $validator \Validator::make($data, [phone_new > [Rule::exists(users, phone)->whereNull(deleted_at),]], [phone_new.exists > 手机号不存在,]);unique 去除软删除字段的校验 // 新增 email>r…...

【PHP + 代码审计】函数详解2.0

&#x1f36c; 博主介绍&#x1f468;‍&#x1f393; 博主介绍&#xff1a;大家好&#xff0c;我是 hacker-routing &#xff0c;很高兴认识大家~ ✨主攻领域&#xff1a;【渗透领域】【应急响应】 【Java、PHP】 【VulnHub靶场复现】【面试分析】 &#x1f389;点赞➕评论➕收…...

宠物智能喂食机方案设计

我们都知道&#xff0c;现如今养宠物的人群已经很多了&#xff0c;主要是青年人居多&#xff0c;他们在独自漂泊的在外的工作&#xff0c;免不了情感泛滥&#xff0c;养一些小动物也是在预料之中。但由于工作或者其他各种因数&#xff0c;养宠人不可时时刻刻在家&#xff0c;对…...

从‘准静态’到‘高效率’:ANSYS Workbench冲压仿真简化建模与计算加速技巧

从‘准静态’到‘高效率’&#xff1a;ANSYS Workbench冲压仿真简化建模与计算加速技巧 冲压成形仿真在工业设计中扮演着越来越重要的角色&#xff0c;但计算资源的消耗和仿真周期的延长常常成为工程师面临的瓶颈。当面对一个复杂的冲压件时&#xff0c;如何在保证工程精度的前…...

上海 GEO 优化机构实力解析:十大标杆服务商核心优势深度呈现

随着生成式 AI 全面打通上海用户信息查询、消费下单全决策链条&#xff0c;超过六成上海本地企业都陷入共性增长难题&#xff1a;自身产品与服务实力出众&#xff0c;却在 AI 智能问答里曝光不足、信息偏差&#xff0c;品牌用户心智持续被同城竞品挤压。不少企业入局上海 GEO 赛…...

如何解锁中兴光猫工厂模式:zteOnu工具实战完整指南

如何解锁中兴光猫工厂模式&#xff1a;zteOnu工具实战完整指南 【免费下载链接】zteOnu A tool that can open ZTE onu device factory mode 项目地址: https://gitcode.com/gh_mirrors/zt/zteOnu 中兴光猫&#xff08;ONU&#xff09;设备通常限制普通用户访问高级配置…...

Qwen-Image-2512惊艳案例:生成符合NES/Genesis/SNES硬件调色板限制的像素图

Qwen-Image-2512惊艳案例&#xff1a;生成符合NES/Genesis/SNES硬件调色板限制的像素图 1. 复古游戏像素艺术的新可能 还记得小时候玩过的那些8-bit和16-bit游戏吗&#xff1f;那些由有限色彩构成的像素世界&#xff0c;如今通过AI技术焕发了新生。Qwen-Image-2512结合Pixel …...

终极Ockam最佳实践:构建生产级分布式系统的20个关键要点

终极Ockam最佳实践&#xff1a;构建生产级分布式系统的20个关键要点 【免费下载链接】ockam Orchestrate end-to-end encryption, cryptographic identities, mutual authentication, and authorization policies between distributed applications – at massive scale. 项目…...

[特殊字符] MoviePy 报错:配置了 ImageMagick 环境变量却不好使?

.This error can be due to the fact that ImageMagick is not installed on your computer, or (for Windows users) that you didnt specify the path to the ImageMagick binary in file conf.py, or that the path you specified is incorrect在使用 Python 的 MoviePy 库制…...

MySQL中如何使用UPPER转大写字母_MySQL文本格式化函数

UPPER(str)仅接受一个字符串参数&#xff0c;将ASCII字母转为大写&#xff0c;非ASCII字符、数字、符号不变&#xff1b;传入NULL返回NULL&#xff1b;在WHERE中使用会导致索引失效&#xff0c;应优先通过校对规则&#xff08;如utf8mb4_general_ci&#xff09;实现大小写不敏感…...

FM调制解调背后的信号处理魔法:用MATLAB拆解通信原理

FM调制解调背后的信号处理魔法&#xff1a;用MATLAB拆解通信原理 在无线通信的世界里&#xff0c;频率调制(FM)技术就像一位优雅的舞者&#xff0c;用频率的变化传递信息。相比幅度调制(AM)&#xff0c;FM以其出色的抗噪声性能&#xff0c;至今仍在广播、对讲机等领域广泛应用。…...

tabula-py错误处理大全:解决10个最常见的表格提取问题

tabula-py错误处理大全&#xff1a;解决10个最常见的表格提取问题 【免费下载链接】tabula-py Simple wrapper of tabula-java: extract table from PDF into pandas DataFrame 项目地址: https://gitcode.com/gh_mirrors/ta/tabula-py 在处理PDF表格数据时&#xff0c;…...

mysql如何禁止用户创建新表_撤销CREATE与ALTER表权限

撤销用户CREATE和ALTER权限后仍能建表&#xff0c;是因为权限叠加生效、GRANT OPTION未撤、角色继承或CREATE TEMPORARY TABLES权限遗漏&#xff1b;必须全面检查并同步撤销DROP、INDEX等关联权限。撤销用户 CREATE 和 ALTER 权限后仍能建表&#xff1f;检查 GRANT OPTION 和角…...