JavaThread线程

目录

程序--进程--线程

程序:

进程:

线程:

进程和线程的关系

创建线程 

单线程模式

代码

图解

运行

代码

运行 

创建线程

方式一

代码

运行 

方式二

代码

运行

总结:

Thread类中常用的方法

1、

代码 

运行 

2、

代码 

运行 

3、

代码 

运行

4、

代码 

运行

5、

代码 

运行

​编辑

线程优先级 

操作系统线程任务调度算法

线程状态

新建 

就绪

运行

阻塞

死亡

守护线程

代码

运行

多线程的概念

何时需要多线程

多线程的优点

多线程的缺点

线程同步

多线程同步

加锁方式1:

Thread类

修饰代码块

代码 

运行

修饰方法

代码

运行

Runnable类

修饰代码块

代码

运行

修饰方法

代码

运行

加锁方式2:

代码

运行

synchronized 与 ReentrantLock区别

相同点:

不同点:

线程通信

代码 

运行

新增创建线程方式

代码

运行


程序--进程--线程

程序:

为解决某种问题,通过计算机语言编写的一系列指令(代码)的集合。

线程中的程序特指的是静态的,安装在硬盘上的代码集合。

进程:

运行中的程序(被加载到内存中),是操作系统进行资源分配的最小单位。

线程:

进程可以进一步细化为线程,是进程内最小的执行单位(具体要做的事情),是cpu进行任务调度的最小单位 。

运行中的QQ就是一个进程,操作系统会为这个进程分配内存资源,一个聊天窗口就认为是一个线程,这多个聊天窗口可以同时被cpu执行,但是这些聊天窗口属于进程,线程是属于进程的。

早期没有线程,早期cpu在执行时是以进程为执行单位的,进程单位还是比较大的,当一个进程运行时,其他的进程就不能执行,所以后来,将进程中的多个任务,细化为线程。cpu执行单位,也从进程转为更小的线程。

进程和线程的关系

1、一个进程可以包含多个线程;

2、一个线程只能隶属于一个进程,线程不能脱离进程存在;

3、一个进行更中至少有一个线程(即主线程)java中的main方法,就是用来启动主线程;

4、在主线程可以创建并启动其他线程;

5、所以线程都共享进程的内存资源。

创建线程 

单线程模式

代码

package com.ffyc.javathread.demo1;public class Demo {public static void main(String[] args) {for (int i = 0; i < 10; i++) {System.out.println("循环1:" + i);}for (int i = 0; i < 10; i++) {System.out.println("循环2:" + i);}}
}

图解

运行

代码
package com.ffyc.javathread.demo1;public class Demo2 {public static void main(String[] args) {for (int i = 0; i < 10; i++) {System.out.println("循环1:" + i);}test();System.out.println("最后的代码");}public static void test(){for (int i = 0; i < 10; i++) {System.out.println("循环2:" + i);}}}

运行 

需求:想在java程序中有几件不相关的事情同时有机会进行进行。

可以在java中创建线程,把一些要执行的任务放在线程中执行,这样的话,都拥有让cpu执行的权力 

创建线程

方式一

MyThread 继承 Thread(线程)
重写Thread类中run()方法,在run()方法中来编写我们需要执行的任务代码 

调用start()启动线程  

代码
package com.ffyc.javathread.demo1; 
public class MyThread extends Thread{//run方法是线程执行任务的方法@Overridepublic void run() {for (int i = 0; i < 10000; i++) {System.out.println("MyThread"+i);}}
}
package com.ffyc.javathread.demo1;public class Test {public static void main(String[] args) {MyThread myThread = new MyThread();/*//切记不能直接调用run(),普通方法调用,并不是启动线程myThread.run();*///启动线程,启动线程后,并不是会立即执行的,需要操作系统的调度myThread.start();for (int i = 0; i < 10000; i++) {System.out.println("Test"+i);}}
}
运行 

方式二

创建一个任务,实现Runnable接口,把这个类不能称为线程,是一个任务类
重写Runnable接口中的run方法

代码
package com.ffyc.javathread.demo2; 
public class MyTask implements Runnable{@Overridepublic void run() {for (int i = 0; i < 10000; i++) {System.out.println("MyTask:"+i);}}
}

main方法是用来启动java主线程的 

package com.ffyc.javathread.demo2;public class Test { public static void main(String[] args) {//创建一个任务的对象MyTask myTask = new MyTask();//真正意义上的创建了一个线程Thread thread = new Thread(myTask);//启动线程,去执行mytask任务thread.start();for (int i = 0; i < 10000; i++) {System.out.println("main:"+i);}}
}
运行

总结:

两种方法后期使用率上,第二种相对更高一些

1、避免了单一继承的局限性,因为java是单继承的 ,继承了Thread类,就不能继承其他类

2、更适合多线程共享同一份资源的场景

Thread类中常用的方法

Thread类表示线程,提供了很多的方法,来对线程进行控制。

1、

run();线程要执行的任务在run方法中进行定义

start();启动java线程的

构造方法

new  Thread(Runnable  runnable);接收一个任务对象

代码 

package com.ffyc.javathread.demo1; 
public class MyThread extends Thread{ @Overridepublic void run() {for (int i = 0; i < 10000; i++) {System.out.println("MyThread"+i);}}
}
package com.ffyc.javathread.demo1;public class Test {public static void main(String[] args) {MyThread myThread = new MyThread(); myThread.start();for (int i = 0; i < 10000; i++) {System.out.println("Test"+i);}}
}

运行 

2、

new  Thread(Runnable  runnable,String  name);接收一个任务对象,并为线程设置名字

setName("我的线程1");为线程设置名字

String  getName();获得线程的名字

Thread.currentThread();在任务中获得当前正在执行的线程

代码 

package com.ffyc.javathread.demo2;public class MyTask_Name implements Runnable{@Overridepublic void run() {//在任务中,我想知道当前是那个线程正在执行//在任务中,通过currentThread()获得当前正在执行的线程Thread thread = Thread.currentThread();System.out.println(thread.getName());}
}
package com.ffyc.javathread.demo2;public class Test_Name {public static void main(String[] args) {MyTask_Name myTask_name = new MyTask_Name();Thread thread1 = new Thread(myTask_name,"线程1");thread1.setName("我的线程1");thread1.start();//又创建了一个线程,把同一个任务交给线程去执行Thread thread2 = new Thread(myTask_name);thread2.start();}
}

运行 

3、

setPriority(int p);设置优先级  1-10之间  默认是5

getPriority();获得优先级

代码 

package com.ffyc.javathread.demo3;public class MyTask implements Runnable{@Overridepublic void run() {//获得当前正在执行对象Thread thread = Thread.currentThread();//获得线程优先级System.out.println(thread.getName()+":"+thread.getPriority());}
}
package com.ffyc.javathread.demo3;public class Test {public static void main(String[] args) {MyTask myTask = new MyTask();Thread t1 = new Thread(myTask,"线程1");Thread t2 = new Thread(myTask,"线程2");//设置线程优先级  1-10之间  默认是5t1.setPriority(8);t2.setPriority(2);t1.start();t2.start();System.out.println(Thread.currentThread().getName()+":"+Thread.currentThread().getPriority());}}

运行

4、

sleep(long m);让线程休眠指定的时间  毫秒单位

代码 

package com.ffyc.javathread.demo3;public class MyTask implements Runnable{@Overridepublic void run() {//获得当前正在执行对象Thread thread = Thread.currentThread();if (thread.getName().equals("线程1")) {try {//让线程休眠 1000毫秒Thread.sleep(4000);} catch (InterruptedException e) {e.printStackTrace();}}//获得线程优先级System.out.println(thread.getName() + ":" + thread.getPriority());}
}
package com.ffyc.javathread.demo3;public class Test {public static void main(String[] args) {MyTask myTask = new MyTask();Thread t1 = new Thread(myTask,"线程1");Thread t2 = new Thread(myTask,"线程2");//设置线程优先级  1-10之间  默认是5t1.setPriority(8);t2.setPriority(2);t1.start();t2.start();System.out.println(Thread.currentThread().getName()+":"+Thread.currentThread().getPriority());}}

运行

5、

join();让其他线程等待当前线程结束

代码 

package com.ffyc.javathread.demo3;public class MyTask implements Runnable{@Overridepublic void run() {//获得当前正在执行对象Thread thread = Thread.currentThread(); //获得线程优先级System.out.println(thread.getName() + ":" + thread.getPriority());}
}
package com.ffyc.javathread.demo3;public class Test {public static void main(String[] args) throws InterruptedException {MyTask myTask = new MyTask();Thread t1 = new Thread(myTask,"线程1");Thread t2 = new Thread(myTask,"线程2"); t2.start();//让其他线程等待当前线程结束后再执行t2.join();t1.start();System.out.println(Thread.currentThread().getName()+":"+Thread.currentThread().getPriority());}}

运行

线程优先级 

事实上,计算机只有一个CPU,各个线程轮流获得CPU的使用权,才能 执行任务;

优先级较高的线程有更多获得CPU的机会,反之亦然;

优先级用整数表示,取值范围是1~10,一般情况下,线程的默认优先级 都是5,但是也可以通过setPriority和getPriority方法来设置或返回优 先级;

操作系统线程任务调度算法

先来先服务(FCFS)调度算法

短作业优先(SJF)调度算法

优先级调度算法

时间片轮转调度算法

高响应比优先级调度算法

多级反馈队列调度算法(集合了前几种算法的优点)

线程状态

线程再它的生命周期中会处于不同的状态;

线程生命周期,线程从创建到销毁,期间经历5个状态:

新建 

new  Thread();处于新建状态,此状态还不能被执行。

调用start()启动线程,让线程进入到就绪状态,

就绪

获得到cpu执行权后,线程进入到cpu执行

运行

运行中的线程可以被切换,又回到就绪状态,也可能因为休眠等原因进入到阻塞状态

阻塞

线程休眠时间到了  回到就绪状态

死亡

当线程中所有的任务执行完了,线程也就自动销毁

守护线程

守护线程也是线程中的一种,区别在于他的结束,如何一个线程是守护线程,那么它会等java中其他线程任务结束后,自动终止。

守护线程是为其他线程提供服务的,例如jvm中的垃圾回收线程,就是一个守护线程

代码

package com.ffyc.javathread.demo4;public class Task implements Runnable{@Overridepublic void run() {while (true){System.out.println("我是守护线程,我为大家服务");}}
}
package com.ffyc.javathread.demo4;public class Test {public static void main(String[] args) {Task task = new Task();Thread thread = new Thread(task);//设置线程为守护线程,设置守护线程必须在启动前设置。thread.setDaemon(true);thread.start();for (int i = 0; i < 10000; i++) {System.out.println("main"+i);}}
}

运行

多线程的概念

多线程是指程序中包含多个执行单元,即在一个程序中可以同时运行多 个不同的线程来执行不同的任务,也就是说允许单个程序创建多个并行 执行的线程来完成各自的任务。

何时需要多线程

程序需要同时执行两个或多个任务。 

程序需要实现一些需要等待的任务时,如用户输入、文件读写操作、 网络操作、搜索等。

多线程的优点

提高程序的处理能力,效率提高了.

提高CPU的利用率.

改善程序结构,将复杂任务分为多个线程,独立运行

多线程的缺点

线程也是程序,所以线程需要占用内存,线程越多占用内存也越多(小问题  可提升硬件设备);

多线程需要协调和管理,所以需要跟踪管理线程,使得cpu开销变大;

线程之间同时对共享资源的访问会相互影响,如果不加以控制会导致数据 出错.

线程同步

确保一个时间点只有一个线程访问共享资源。可以给共享资源加一把锁,哪个 线程获取了这把锁,才有权利访问该共享资源。

多线程同步

多个线程同时读写同一份共享资源时,可能会引起冲突。所以引入线程“同步”机制, 即各线程间要有先来后到;

同步 = 排队 + 锁  一次只能由一个线程访问共享资源

加锁方式1:

多个线程访问同一个共享的数据,如果不加以控制,在理论上就会出现问题

Thread类

使用synchronized关键字

修饰代码块

同步对象要求:

锁对象,必须多个线程对应的是同一个对象,可以是java中任何类的对象

作用:可以记录有没有线程进入到同步代码块中

synchronized (锁对象){ 
         使用锁对象的对象头中的一块空间来记录锁的状态
         同步代码块
}  

代码 
package com.ffyc.javathread.demo5;public class TicketThread extends Thread{String name; //静态变量,在内存中只有一份,两个线程对象共用同一个static int num = 10;//必须确保多个线程对应的是同一个对象即可static String s = new String();@Overridepublic void run() {while (true){synchronized (s){if(num > 0){try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName()+"买到了:"+num--);}else{break;}}}}
}
package com.ffyc.javathread.demo5;public class Test {public static void main(String[] args) { TicketThread t1 = new TicketThread();t1.setName("窗口1");TicketThread t2 = new TicketThread();t2.setName("窗口2");t1.start();t2.start();}
}
运行

修饰方法

1、锁不需要我们提供了,会默认提供锁对象

2、synchronized如果修饰的是非静态的方法,锁对象是this

      synchronized如果修饰的是静态方法,锁对象是类的Class对象

      一个类只有一个Class类对象

代码
package com.ffyc.javathread.demo5;public class TicketThread extends Thread{String name;//静态变量,在内存中只有一份,两个线程对象共用同一个static int num = 10; @Overridepublic void run() {while (true){if(num <= 0){break;}TicketThread.printTicket();}} public static synchronized void printTicket(){if(num > 0){try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName()+"买到了:"+num--);}}
}
package com.ffyc.javathread.demo5;public class Test {public static void main(String[] args) { TicketThread t1 = new TicketThread();t1.setName("窗口1");TicketThread t2 = new TicketThread();t2.setName("窗口2");t1.start();t2.start();}
}
运行

Runnable类

修饰代码块
代码
package com.ffyc.javathread.demo6;import com.ffyc.javathread.demo5.TicketThread;public class Ticket implements Runnable{//对于多个线程来说,票数只有一份int num = 10;@Overridepublic void run() {while (true){//this只有一个synchronized (this){if(num > 0){try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName()+"买到了:"+num--);}else{break;}}}}
}
package com.ffyc.javathread.demo6;public class Test {public static void main(String[] args) {//创建了一个出票的任务Ticket ticket = new Ticket();Thread t1 = new Thread(ticket,"窗口1");Thread t2 = new Thread(ticket,"窗口2");t1.start();t2.start();}
}
运行

修饰方法
代码
package com.ffyc.javathread.demo6;import com.ffyc.javathread.demo5.TicketThread;public class Ticket implements Runnable{//对于多个线程来说,票数只有一份int num = 10;@Overridepublic void run() {while (true){if(num <= 0){break;}printTicket();}}public synchronized void printTicket(){if(num > 0){try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName()+"买到了:"+num--);}}
}
package com.ffyc.javathread.demo6;public class Test {public static void main(String[] args) {//创建了一个出票的任务Ticket ticket = new Ticket();Thread t1 = new Thread(ticket,"窗口1");Thread t2 = new Thread(ticket,"窗口2");t1.start();t2.start();}
}
运行

加锁方式2:

使用jdk中提供的ReentrantLock类实现加锁

ReentrantLock只能对某一段代码块加锁,不能对整个方法加锁

代码
package com.ffyc.javathread.demo7;import java.util.concurrent.locks.ReentrantLock;public class TicketTask implements Runnable{int num = 10;//提供一个实现加锁的对象ReentrantLock reentrantLock = new ReentrantLock();@Overridepublic void run() {while (true){//加锁reentrantLock.lock();try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}try {if(num > 0){System.out.println(Thread.currentThread().getName()+":买到了"+num--);}else {break;}}finally {//在finally块中保证锁必须释放//释放锁reentrantLock.unlock();}}}
}
package com.ffyc.javathread.demo7;public class Test {public static void main(String[] args) {TicketTask ticketTask = new TicketTask();Thread t1 = new Thread(ticketTask,"窗口1");Thread t2 = new Thread(ticketTask,"窗口2");t1.start();t2.start();}
}

运行

synchronized 与 ReentrantLock区别

相同点:

都实现了加锁的功能

不同点:

1、synchronized是一个关键字,ReentrantLock是一个类

2、synchronized修饰代码块和方法ReentrantLock只能修饰代码块

3、synchronized可以隐式的加锁和释放锁,运行过程中如果出现了异常可以自动释放

     ReentrantLock需要手动的添加锁和释放锁,建议在finally代码块中释放锁。

线程通信

线程间的通信(在同步代码块的基础上,使用wait,notify来对线程进行控制) 

      wait(); notify();  notifyAll();
      这三个方法都是Object类中定义的方法
      这三个方法必须在同步代码块中使用
      这三个方法必须通过为锁的对象调用

代码 

package com.ffyc.javathread.demo8;public class PrintNumThread extends Thread{static int num = 0;static Object o = new Object(); @Overridepublic void run() {while (true){synchronized (o){//唤醒等待中的线程o.notify();if(num < 100){System.out.println(Thread.currentThread().getName()+":"+ ++num);}else {break;}try {//让线程等待,同时释放锁,等待的线程不能自己醒来,必须让另一个线程唤醒o.wait();} catch (InterruptedException e) {e.printStackTrace();}}}}
}
package com.ffyc.javathread.demo8;public class Test {public static void main(String[] args) {PrintNumThread p1 = new PrintNumThread();p1.setName("线程1");PrintNumThread p2 = new PrintNumThread();p2.setName("线程2");p1.start();p2.start();}
}

运行

......

新增创建线程方式

实现Callable接口,重写call()方法

call()可以有返回值,可以抛出异常,还可以自定义返回结果的类型

代码

package com.ffyc.javathread.demo10;import java.util.concurrent.Callable;public class SumTask<T> implements Callable<T> {@Overridepublic T call() throws Exception {Integer i = 0;for (int j = 0; j < 10; j++) {i+=j;}return (T)i;}
}
package com.ffyc.javathread.demo10;import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;public class Test {public static void main(String[] args) {SumTask<Integer> sumTask = new SumTask<>();FutureTask<Integer> futureTask = new FutureTask(sumTask);Thread thread = new Thread(futureTask);thread.start();try {//获取到线程执行结果Integer integer = futureTask.get();System.out.println(integer);} catch (InterruptedException e) {e.printStackTrace();} catch (ExecutionException e) {e.printStackTrace();}}
}

运行

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/807297.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

电脑剪切复制到u盘文件丢失怎么办?未备份者的应急指南

在日常生活和工作中&#xff0c;我们经常使用电脑和U盘进行文件的传输和备份。然而&#xff0c;在剪切复制文件到U盘的过程中&#xff0c;有时可能会遇到文件丢失或无法找到的问题&#xff0c;而这时又没有备份&#xff0c;这无疑让人头疼不已。那么&#xff0c;面对这种情况&a…

java的aop实现方式

java的aop可以通过三种方式来实现 1.使用ajc编译的插件来完成增强 这种方法会直接修改编译完成的class文件&#xff0c;不需要依赖springboot 2.动态代理proxy 2.1cglib 可以代理接口&#xff0c;方法等&#xff0c;这种方式代理类是目标类的子类&#xff0c;要求目标类不…

使用 EFCore 和 PostgreSQL 实现向量存储及检索

随着 ChatGPT 的兴起及其背后的 AIGC 产业不断升温,向量数据库已成为备受业界瞩目的领域。FAISS、Milvus、Pinecone、Chroma、Qdrant 等产品层出不穷。市场调研公司 MarketsandMarkets 的数据显示,全球向量数据库市场规模预计将从 2020 年的 3.2 亿美元增长至 2025 年的 10.5…

Ps 滤镜:风格化

风格化 Stylize滤镜通过置换像素和通过查找并增加图像的对比度&#xff0c;基于原图像生成绘画或印象派的效果。 查找边缘 Find Edges “查找边缘”滤镜通过分析图像的色彩和亮度变化来识别边缘。 这种处理方式使得图像的主要轮廓以一种艺术化的线条形式被强调出来&#xff0c;…

大语言模型的指令调优:综述

&#x1f349; CSDN 叶庭云&#xff1a;https://yetingyun.blog.csdn.net/ 论文标题&#xff1a;Instruction Tuning for Large Language Models: A Survey 论文地址&#xff1a;https://arxiv.org/abs/2308.10792 指令调优是提升大语言模型&#xff08;LLMs&#xff09;性能…

python爬虫3-xpath批量定位元素的方法

以爬取豆瓣影评的电影名称为例。 第一步 鼠标右键单击&#xff0c;选择【检查】 第二步 切换到【元素】标签&#xff0c;展示源代码 选择下图的小箭头&#xff0c;再选择想要定位的文本&#xff0c;源代码会自动定位到该文本。 第三步 鼠标放在该文本的源代码上&#xff0c;…

Pytorch官方FlashAttention速度测试

在Pytorch的2.2版本更新文档中&#xff0c;官方重点强调了通过实现FlashAtteneion-v2实现了对scaled_dot_product_attention约2X左右的加速。 今天抽空亲自试了下&#xff0c;看看加速效果是否如官方所说。测试前需要将Pytorch的版本更新到2.2及以上&#xff0c;下面是测试代码…

Prometheus-Grafana基础篇安装绘图

首先Prometheus安装 1、下载 https://prometheus.io/download/ 官网路径可以去这儿下载 2、如图&#xff1a; 3.解压&#xff1a; tar -xf prometheus-2.6.1.linux-amd64 cd prometheus-2.6.1.linux-amd64 4.配置文件说明&#xff1a; vim prometheus.yml 5.启动Promethe…

kail渗透工具之nmap的使用方法

准备工作&#xff1a;开启两台虚拟机和一台Windows主机 kail Linux攻击机&#xff1a;192.168.80.131 red hat靶机&#xff1a;192.168.80.129 Windows主机&#xff1a;192.168.252.42 1、nmap扫描工具的简介 nmap是用来探测计算机网络上的主机和服务的一种安全扫描器。为了绘…

2024年视频号小店无货源,你一定要尝试一下,出九单收入1W+

大家好&#xff0c;我是电商花花。 如果说去年视频号的流量还差点意思&#xff0c;那么今年的视频号销量一定是非常高的&#xff0c;随着视频号的扩展&#xff0c;也让更多的创业者和博主入驻视频号&#xff0c;让更多人了解到了视频号小店&#xff0c;是这样赚钱的。 首先&am…

深水采样器小口径特氟龙材质FEP贝勒管

FEP贝勒管&#xff0c;深水采样器(bailers tube)&#xff0c;是一种经济型便携式水质采样器&#xff0c;操作简单&#xff0c;使用方便&#xff0c;性价比高&#xff0c;能大限度的保证样品的真实性。采样管直径很小&#xff0c;能够采取小口径的深水井水样。是一款简单实用&am…

磁盘管理显示u盘无媒体怎么恢复数据

随着科技的发展&#xff0c;U盘已成为我们日常生活和工作中不可或缺的数据存储工具。然而&#xff0c;当我们在使用U盘时&#xff0c;有时会遇到“磁盘管理显示U盘无媒体”的困扰。面对这一问题&#xff0c;许多用户可能会感到惊慌失措&#xff0c;担心数据丢失。本文将为您详细…

c语言例题,计算1/1-1/2+1/3-1/4+1/5……+1/99-1/100的值,打印结果

例题&#xff1a;计算分式1/1-1/21/3-1/41/5……1/99-1/100的值&#xff0c;打印结果 根据题目&#xff0c;我们知道需要计算的是一个固定值&#xff0c; 先定义三个变量来当作分式里的三个值&#xff0c;变量i当作分式里的分母部分&#xff0c;通过for循环来实现分母每次循环…

存储器层次结构

内存 对于内存已经不像曾经那般陌生了&#xff0c;在汇编中&#xff0c;我们大量接触了内存&#xff0c;但是我们还没有对它有个确切、深入的了解。 内存其实叫做随机访问存储器&#xff08;RAM&#xff0c;Random Access Memory&#xff09;&#xff0c;最基本的存储单位称为…

怎么获取OpenAI的api-key【人工智能】

怎么获取OpenAI的api-key【人工智能】 前言版权推荐怎么获取OpenAI的api-key1.访问控制台2.点击API keys3.点击Start verification4.点击新建密钥 最后 前言 2024-4-11 11:32:06 以下内容源自《【人工智能】》 仅供学习交流使用 版权 禁止其他平台发布时删除以下此话 本文首…

自动挡变速箱 相关的东西研究

1. 原来大众POLO变速箱故障时&#xff0c;详细的维修流程是这样的&#xff01;_易车 原来大众POLO变速箱故障时&#xff0c;详细的维修流程是这样的&#xff01;_易车 大众POLO七速干式双离合变速箱OAM 本文主要讲解的是大众POLO双离合变速箱的维修案例&#xff0c;首先说一…

【C++】模版

目录 一、泛型编程二、函数模板2.1 函数模板概念2.2 函数模板格式2.3 函数模板的原理2.4 函数模板的实例化2.5 模板参数的匹配原则 三、类模板3.1 类模板的定义格式3.2 类模板的实例化 四、非类型模板参数五、模板的特化5.1 概念5.2 函数模板特化5.3 类模板特化5.3.1 全特化5.3…

JS加密:对比JScrambler和JShaman加密效果

本文&#xff0c;以一个实例&#xff0c;比对JS加密两大神器&#xff1a;JScrambler、JShaman的加密结果&#xff0c;看看谁的加密效果更好。 注&#xff1a;本文不是技术文章&#xff0c;仅仅从加密结果的“型”上简单观查&#xff0c;不做技术分析&#xff0c;仅看哪个加密代…

【计算机考研】数据结构都不会,没有思路,怎么办?

基础阶段&#xff0c;并不需要过于专门地练习算法。重点应该放在对各种数据结构原理的深入理解上&#xff0c;也可以说先学会做选择题、应用题。 因为在考试中&#xff0c;大部分的算法题目&#xff0c;尤其是大题&#xff0c;往往可以通过简单的暴力解决方案得到较高的分数。…

计算机服务器中了devicdata勒索病毒怎么办,devicdata勒索病毒解密数据恢复

在企业的生产运营过程中&#xff0c;网络为企业的发展带来了极大便利&#xff0c;大大提升了企业生产效率&#xff0c;但网络在为人们提供便利的同时&#xff0c;也为企业的数据安全带来隐患&#xff0c;近期&#xff0c;云天数据恢复中心接到多家企业的求助&#xff0c;企业的…