二十章 多线程

news2024/9/28 19:20:58

线程简介


        在 Java 中,并发机制非常重要。在以往的程序设计中,我们都是一个任务完成后再进行下一个任务,这样下一个任务的开始必须等待前一个任务的结束。Java 语言提供了并发机制,程序员可以在程序中执行多个线程,每一个线程完成一个功能,并与其他线程并发执行,这种机制被称为多线程。然而,有必要强调的是,并不是所有编程语言都支持多线程。

创建线程

继承Thread 类


        Thread 类时 java.lang 包中的一个类,从类中实例化的对象代表线程,程序员启动一个新线程需要建立 Thread 实例。

继承 Thread 类创建一个新的线程的语法如下:

public class ThreadTest extends Thread{
}

Thread 对象需要一个任务来执行,任务是指线程在启动时执行的工作,该工作的功能代码被写在

run()方法中。run()方法必须使用以下语法格式:

public void run(){
}

主方法线程自动由 Java虚拟机负责,程序员负责启动自己的线程。代码如下:

public static void main(Stringl args) {
new ThreadTest().start();

}

例:让线程循环打印1~10的数字 

 
  1. public class ThreadTest extends Thread{
    
    public void run() {
    
    for(int i=0;i<=10;i++) {
    
    System.out.print(i+" ");
    
    }
    
    }
    
    
    public static void main(String[] args) {
    
    ThreadTest t=new ThreadTest();
    
    t.start();
    
    }
    
    }

 

实现 Runnable 接口


        线程都是通过扩展 Thread 类来创建的,如果程序员需要继承其他类(非Thread 类),而且还要是当前类实现多线程,那么可以通过  Runnable 接口来实现。

        实现 Runnable 接口的程序会创建一个 Thread 对象,并将 Runnable 对象与 Thread 对象相关联。

使用 Runnable 接口启动新的线程的步骤:

建立 Runnable 对象
使用参数为 Runnable 对象的构造方法创建 Thread 实例
调用 start() 方法启动线程


例:让窗体的图标动起来
 

 
  1. import java.awt.Container;
    
    
    import javax.swing.Icon;
    
    import javax.swing.ImageIcon;
    
    import javax.swing.JFrame;
    
    import javax.swing.JLabel;
    
    
    public class SwingAndThread extends JFrame{
    
    int count=0;//图标坐标
    
    
    public SwingAndThread(){
    
    setBounds(300,200,250,100);//绝对定位窗体大小与位置
    
    Container cotainer=getContentPane();//主容器
    
    cotainer.setLayout(null);//使窗体不使用任何布局管理器
    
    
    Icon icon=new ImageIcon("1.gif");//图标对象
    
    JLabel jl=new JLabel(icon);//显示图标的标签
    
    jl.setBounds(10,10,200,50);//设置标签的位置与大小
    
    Thread t=new Thread() {//定义匿名线程对象
    
    public void run() {
    
    while(true) {
    
    jl.setBounds(count,10,200,50);//将标签的横坐标用变量表示
    
    try {
    
    Thread.sleep(500);//使线程休眠500毫秒
    
    }catch(InterruptedException e) {
    
    e.printStackTrace();
    
    }
    
    count+=4;//使横坐标每次增加4
    
    if(count>=120) {
    
    count=10;//当图标到达标签的最右时,时其回到标签做左边
    
    }
    
    }
    
    
    }
    
    };
    
    t.start();//启动线程
    
    cotainer.add(jl);//将标签添加到容器中
    
    setVisible(true);//使窗体可见
    
    setDefaultCloseOperation(EXIT_ON_CLOSE);//设置窗体的关闭方式
    
    }
    
    
    public static void main(String[] args) {
    
    new SwingAndThread();
    
    
    }
    
    }

 

线程的生命周期


        一旦线程进入可执行状态,它会在就绪与运行状态下转换,同时也有可能进入等待,休眠,赌塞或死亡状态。

要使线程处于就绪,有以下几种方法:

调用 sleep() 方法。
调用 wait() 方法。
等待输入/输出完成。


当线程处于就绪状态后,可以用以下几种方法使线程再次进入运行状态:

线程调用 notify() 方法。
线程调用 notifyAll() 方法。
线程调用 interrupt() 方法。
线程的休眠时间结束。
输入/输出结束。


操作线程的方法


 线程的休眠


        一种能控制线程行为的方法是调用 sleep() 方法需要一个参数用于指定该线程休眠的时间,该时间以毫秒为单位。

例:每0.1秒绘制一条随机颜色的线条
 

 
  1. import java.awt.Color;
    
    import java.awt.Graphics;
    
    import java.util.Random;
    
    
    import javax.swing.JFrame;
    
    
    public class SleepMethodTest extends JFrame{
    
    private static Color[] color= {Color.BLACK,Color.BLUE,Color.CYAN,Color.GREEN,
    
    Color.RED,Color.ORANGE,Color.YELLOW,Color.PINK,Color.LIGHT_GRAY};//定义颜色数组
    
    private static final Random rand=new Random();//创建随机对象
    
    
    private static Color getC() {//获取随机颜色值的方法
    
    return color[rand.nextInt(color.length)];
    
    }
    
    
    public SleepMethodTest(){
    
    Thread t=new Thread(new Runnable() {//创建匿名线程对象
    
    int x=30;//定义初始坐标
    
    int y=50;
    
    
    public void run() {
    
    while(true) {//无限循环
    
    try {
    
    Thread.sleep(100);//线程休眠0.1秒
    
    }catch(InterruptedException e) {
    
    e.printStackTrace();
    
    }
    
    Graphics graphics=getGraphics();//获取组件绘图上下文对象
    
    graphics.setColor(getC());//设置绘图颜色
    
    graphics.drawLine(x, y,150, y++);//绘制直线并递增垂直坐标
    
    if(y>=180) {
    
    y=50;
    
    }
    
    }
    
    }
    
    });
    
    t.start();//启动线程
    
    }
    
    
    public static void main(String[] args) {
    
    init(new SleepMethodTest(),200,200);
    
    
    }
    
    
    public static void init(JFrame frame,int width,int height) {//初始化程序界面的方法
    
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    
    frame.setSize(width, height);
    
    frame.setVisible(true);
    
    }
    
    }

 

线程的加入

        当某个线程使用 join() 方法的加入一个线程时,另外一个线程会等待该线程执行完毕后再继续执行。

代码:

 
  1. import java.awt.BorderLayout;
    
    
    import javax.swing.JFrame;
    
    import javax.swing.JProgressBar;
    
    
    public class JoinTest extends JFrame{
    
    //定义两个线程
    
    private Thread threadA;
    
    private Thread threadB;
    
    //定义两个进度条组件
    
    private JProgressBar porgressBar=new JProgressBar();
    
    private JProgressBar porgressBar2=new JProgressBar();
    
    
    
    public static void main(String[] args) {
    
    JoinTest test=new JoinTest();
    
    test.setVisible(true);
    
    
    }
    
    public JoinTest() {
    
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    
    setBounds(200,200,200,100);
    
    getContentPane().add(porgressBar,BorderLayout.NORTH);//将进度条设置在窗体最北面
    
    getContentPane().add(porgressBar2,BorderLayout.SOUTH);//将进度条设置在窗体最南面
    
    //设置进度条显示数字字符
    
    porgressBar.setStringPainted(true);
    
    porgressBar2.setStringPainted(true);
    
    //使用匿名内部类形式初始化 Thread 实例
    
    threadA=new Thread(new Runnable() {
    
    int count=0;
    
    public void run() {//重写 run()方法
    
    while(true) {
    
    porgressBar.setValue(++count);//设置进度条的当前值
    
    try {
    
    Thread.sleep(100);//使线程A休眠100毫秒
    
    threadB.join();//使线程B调用join()方法
    
    }catch(InterruptedException e) {
    
    e.printStackTrace();
    
    }
    
    }
    
    }
    
    });
    
    threadA.start();//启动线程A
    
    threadB=new Thread(new Runnable() {
    
    int count=0;
    
    public void run() {
    
    while(true) {
    
    porgressBar2.setValue(++count);//设置进度条的当前值
    
    try {
    
    Thread.sleep(100);//使线程休眠100毫秒
    
    }catch(InterruptedException e) {
    
    e.printStackTrace();
    
    }
    
    if(count==100)//当count变量增长为100时
    
    break;//跳出循环
    
    }
    
    }
    
    });
    
    threadB.start();//启动线程B
    
    }
    
    
    }

 

线程的中断


        以往有时候会使用 stop() 方法停止线程,但当前版本的 JDK 早已废除了 stop() 方法,不建议使用 stop() 方法来停止一个线程的运行。现在提倡在 run() 方法中使用无限循环的形式,然后使用一个布尔型标记控制循环的停止。

        如果线程是因为使用了 sleep()或 wait()方法进入了就入就绪状态,可以使用 Thread()方法,同时程序破除了 InterruptedException 异常,在异常处理时结束了 while 循环。在项目中,经常在这里执行关闭数据连接和关闭 Socket 连接等操作。

 代码: 
 

 
  1. import java.awt.BorderLayout;
    
    import java.awt.event.ActionEvent;
    
    import java.awt.event.ActionListener;
    
    
    import javax.swing.JButton;
    
    import javax.swing.JFrame;
    
    import javax.swing.JProgressBar;
    
    
    public class InterruptedSwing extends JFrame{
    
    
    public InterruptedSwing (){
    
    JProgressBar porgressBar=new JProgressBar();//创建进度条
    
    getContentPane().add(porgressBar,BorderLayout.NORTH);//将进度条设置在窗体最北面
    
    JButton button=new JButton("停止");
    
    getContentPane().add(button,BorderLayout.SOUTH);//将进度条设置在窗体最北面
    
    //设置进度条显示数字字符
    
    porgressBar.setStringPainted(true);
    
    //使用匿名内部类形式初始化 Thread 实例
    
    Thread t=new Thread(new Runnable() {
    
    int count=0;
    
    
    public void run() {//重写 run()方法
    
    while(true) {
    
    porgressBar.setValue(++count);//设置进度条的当前值
    
    try {
    
    Thread.sleep(100);//使线程休眠100毫秒
    
    }catch(InterruptedException e) {//捕捉InterruptedException异常
    
    System.out.println("但前线程被中断");
    
    break;
    
    }
    
    }
    
    }
    
    });
    
    
    button.addActionListener(new ActionListener() {
    
    
    @Override
    
    public void actionPerformed(ActionEvent e) {
    
    t.interrupt();//中断线程
    
    
    }
    
    
    });
    
    t.start();//启动线程
    
    }
    
    
    public static void init(JFrame frame,int width,int height) {//初始化程序界面的方法
    
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    
    frame.setSize(width, height);
    
    frame.setVisible(true);
    
    }
    
    
    public static void main(String[] args) {
    
    init(new InterruptedSwing(),100,100);
    
    
    }
    
    }

 

线程的礼让


         Thread 类提供了一种礼让方法,使用 yied()方法表示,它只是给当前正处于运行状态的线程一个提醒,告知它可以将资源礼让给其他线程,但这仅是一种暗示,没有任何一种机制保证当前线程会将资源礼让。

        yied()方法使具有同样优先级的线程有进入可执行状态的机会,在当前线程放弃执行权时再度回到就绪状态。对于支持多任务的操作系统来说,不需要调用 yied()方法,因为操作系统会为线程自动分配 CPU 时间来执行。

线程的优先级


        每个线程都具有各自的优先级,线程的优先级可以表明在程序中该线程的重要性,如果有很多线程处于就绪状态,系统会根据优先级来决定首先使哪个线程进入运行状态。但这并不意味着低优先级的线程得不到运行,而只是它运行的概率比较小,如垃圾回收线程的优先级就按照较低。

        线程的优先级可以使用 setPriority()方法调整,如果使用该方法设置的优先级不在 1~10,将产生IllegalArgumentException 异常。

代码: 
 

 
  1.  

    public class PriorityTest implements Runnable{
    
    String name;
    
    
    public PriorityTest(String name) {
    
    this.name=name;
    
    }
    
    
    @Override
    
    public void run() {
    
    String tmp="";
    
    for(int i=0;i<5000;i++) {
    
    tmp+=i;//完成5万次字符串拼接
    
    }
    
    System.out.println(name+"线程完车任务");
    
    }
    
    
    public static void main(String[] args) {
    
    Thread a=new Thread(new PriorityTest("A"));
    
    a.setPriority(1);//A线程优先级最小
    
    Thread b=new Thread(new PriorityTest("B"));
    
    b.setPriority(3);
    
    Thread c=new Thread(new PriorityTest("C"));
    
    c.setPriority(7);
    
    Thread d=new Thread(new PriorityTest("D"));
    
    d.setPriority(10);//D线程优先级最大
    
    a.start();
    
    b.start();
    
    c.start();
    
    d.start();
    
    }
    
    }

 

线程同步


        在单线程程序中,每次只能做一件事情,后面的事情需要等待前面的事情完成后才可以进行,但是如果使用多线程程序,就会发生两个线程抢占资源的问题,如两个人同事说话、两个人同时过同一个独木桥。所以,在多线程编程中需要防止这些资源访问的冲突。Java 提供了线程同步的机制来防止资源访问的冲突。

线程安全


        在编写多线程时时,因该考虑到线程安全问题。实质上线程问题来源两个线程同时存取单一对象的数据。

代码: 

 
  1.  

    public class ThreadSafeTest implements Runnable{
    
    int num = 10; //设置当前票数
    
    
    
    @Override
    
    public void run() {
    
    while(true) { //设置无限循环
    
    if(num >0) { //设置当前票数是否大于0
    
    try {
    
    Thread.sleep(100); //使当前线程休眠100毫秒
    
    }catch(InterruptedException e) {
    
    e.printStackTrace();
    
    }
    
    System.out.println(Thread.currentThread().getName()+"------票数"+num--); //票数减一
    
    }
    
    }
    
    }
    
    
    public static void main(String[] args) {
    
    ThreadSafeTest t = new ThreadSafeTest(); //实例化类对象
    
    Thread tA = new Thread(t,"线程一"); //以该类对象分别实例化4个线程
    
    Thread tB = new Thread(t,"线程二");
    
    Thread tC = new Thread(t,"线程三");
    
    Thread tD = new Thread(t,"线程四");
    
    tA.start(); //分别启动线程
    
    tB.start();
    
    tC.start();
    
    tD.start();
    
    }
    
    }

线程同步机制


        所以解决多线程资源问题的方法基本上都是采用给定时间只允许一个线程访问共享资源的方法。这时就需要给共享源上一道锁。

1、同步块


        Java中提供了同步机制,可以有效地防止资源冲突。同步机制使用 synchronized 关键字,使用该关键字包含的代码块称为同步块,也称临界区,语法如下:

synchronized(Object){
}

代码: 
 

 
  1.  

    public class ThreadSafeTest implements Runnable{
    
    int num = 10; //设置当前票数
    
    
    
    @Override
    
    public void run() {
    
    while(true) { //设置无限循环
    
    synchronized(this) { //同步锁
    
    if(num >0) { //设置当前票数是否大于0
    
    try {
    
    Thread.sleep(100); //使当前线程休眠100毫秒
    
    }catch(InterruptedException e) {
    
    e.printStackTrace();
    
    }
    
    System.out.println(Thread.currentThread().getName()+"------票数"+num--); //票数减一
    
    }
    
    }
    
    }
    
    }
    
    public static void main(String[] args) {
    
    ThreadSafeTest t = new ThreadSafeTest(); //实例化类对象
    
    Thread tA = new Thread(t,"线程一"); //以该类对象分别实例化4个线程
    
    Thread tB = new Thread(t,"线程二");
    
    Thread tC = new Thread(t,"线程三");
    
    Thread tD = new Thread(t,"线程四");
    
    tA.start(); //分别启动线程
    
    tB.start();
    
    tC.start();
    
    tD.start();
    
    }
    
    }

 

2、同步方法

同步方法就是在方法前面用 synchronized 关键字修饰的方法,语法如下:

synchronized void f(){

}

 
  1.  

    public class ThreadSafeTest implements Runnable{
    
    int num = 10; //设置当前票数
    
    public synchronized void doit() { //定义同步方法
    
    if(num >0) { //设置当前票数是否大于0
    
    try {
    
    Thread.sleep(10); //使当前线程休眠100毫秒
    
    }catch(InterruptedException e) {
    
    e.printStackTrace();
    
    }
    
    System.out.println(Thread.currentThread().getName()+"------票数"+num--); //票数减一
    
    }
    
    }
    
    
    @Override
    
    public void run() {
    
    while(true) { //设置无限循环
    
    doit(); //在run()方法中调用该同步方法
    
    }
    
    }
    
    
    public static void main(String[] args) {
    
    ThreadSafeTest t = new ThreadSafeTest(); //实例化类对象
    
    Thread tA = new Thread(t,"线程一"); //以该类对象分别实例化4个线程
    
    Thread tB = new Thread(t,"线程二");
    
    Thread tC = new Thread(t,"线程三");
    
    Thread tD = new Thread(t,"线程四");
    
    tA.start(); //分别启动线程
    
    tB.start();
    
    tC.start();
    
    tD.start();
    
    }
    
    }

运行结果: 

 

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

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

相关文章

上门预约互联网干洗店洗鞋店小程序开发

很多时候可能大家的衣服鞋子需要干洗&#xff0c;但又不想出门送去店里&#xff0c;大家就可以使用手机线上下单预约取货&#xff0c;会有专门的人上门来取衣服&#xff0c;让你能够轻松的进行洗护。 闪站侠洗衣洗鞋小程序&#xff0c;提供了足不出户就能预约人员上门去 衣送洗…

【刷题笔记】匹配字符串||KMP||动图解析||符合思维方式

找出字符串中第一个匹配项的下标 1 题目描述 https://leetcode.cn/problems/find-the-index-of-the-first-occurrence-in-a-string/ 给你两个字符串 haystack 和 needle &#xff0c;请你在 haystack 字符串中找出 needle 字符串的第一个匹配项的下标&#xff08;下标从 0 开…

Swift下如何使用#if条件编译

一、OC使用条件编译 OC中可以使用宏定义&#xff0c;再使用条件编译 #define USER_CUSTOM使用 #if USER_CUSTOM //其他代码 #endif二、Swift使用条件编译 Swift 不像ObjectC一样&#xff0c;通过定义一个变量&#xff0c;然后使用**#if #endif** 方法。swift需要设置一下才能…

SpringBoot错误处理机制(ControllerAdvice+ExceptionHandler自定义错误处理、默认机制源码分析、错误处理实战)

目录 1. SpringBoot自己对错误进行处理1.1 给一个Controller进行错误处理1.2 使用ControllerAdvice统一处理错误 2. 默认机制源码解析3. 错误处理机制实战 1. SpringBoot自己对错误进行处理 1.1 给一个Controller进行错误处理 使用ExceptionHandler&#xff0c;处理一个Conto…

【电源芯片】ZTP7193

&#x1f6a9; WRITE IN FRONT &#x1f6a9; &#x1f50e; 介绍&#xff1a;"謓泽"正在路上朝着"攻城狮"方向"前进四" &#x1f50e;&#x1f3c5; 荣誉&#xff1a;2021|2022年度博客之星物联网与嵌入式开发TOP5|TOP4、2021|2222年获评百大…

销售流程中如何有效开发客户

在销售的海洋中&#xff0c;如何游刃有余地开发客户是一大关键。这需要深入了解你的目标客户&#xff0c;制定一份精细的销售计划&#xff0c;选择最合适的沟通方式&#xff0c;建立信任和信誉&#xff0c;并持续不断地跟进。 每一个潜在的客户都是一颗璀璨的星辰&#xff0c;…

地理坐标系转换

1.EPSG代码 搜索地理坐标系对应的EPSG代码 https://epsg.io/ 常用的地理坐标系EPSG代码&#xff1a; 2. 坐标系转换 转换网址&#xff1a; https://epsg.io/transform &#xff08;1&#xff09;修改 input coordinate system 和 output coordinate system&#xff0c; 可以…

【开源】基于Vue.js的农村物流配送系统的设计和实现

项目编号&#xff1a; S 024 &#xff0c;文末获取源码。 \color{red}{项目编号&#xff1a;S024&#xff0c;文末获取源码。} 项目编号&#xff1a;S024&#xff0c;文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 系统登录、注册界面2.2 系统功能2.2…

人工智能学习2(python数据清洗)

编译工具&#xff1a;PyCharm 一.数据清洗 转化数据类型、处理重复数据、处理缺失数据 import pandas as pddf pd.read_csv("/data.csv") df.sample(10) # 用于随机获取数据并返回结果 df.head(10) # 查看前十条数据 df.tail(10) # 查看后十条数据 df.shape …

Zookeeper 实战 | Zookeeper 和Spring Cloud相结合解决分布式锁、服务注册与发现、配置管理

专栏集锦&#xff0c;大佬们可以收藏以备不时之需&#xff1a; Spring Cloud 专栏&#xff1a;http://t.csdnimg.cn/WDmJ9 Python 专栏&#xff1a;http://t.csdnimg.cn/hMwPR Redis 专栏&#xff1a;http://t.csdnimg.cn/Qq0Xc TensorFlow 专栏&#xff1a;http://t.csdni…

Emeya散发的时代之光,似乎正盖过Panamera的余晖

路特斯Emeya的首秀象征着在超豪华汽车领域&#xff0c;纯电与超跑轿车的绝美融合正式拉开序幕。自由与灵感的碰撞&#xff0c;诗意与理想的贯通&#xff0c;汽车工业的性感似乎在Emeya上出现了全新的表达。 但短短不到一周的时间&#xff0c;我们又见到了全新Panamera的首秀。…

四招心理博弈术,让别人不敢欺负你,敬你三分

教你四招心理博弈术&#xff0c;让别人不敢欺负你&#xff0c;无论在职场中还是跟朋友交往中&#xff0c;为什么总是有人敢欺负你呢&#xff0c;是因为你不懂得人性博弈。其本质原因&#xff0c;是你做人没有边界感&#xff0c;或者没有原则&#xff0c;即便你有原则&#xff0…

【APUE】进程间通信

目录 一、管道 1.1 匿名管道 1.2 命名管道 二、XSI IPC 2.1 概述 2.2 消息队列 2.2.1 msgget 2.2.2 msgsnd 2.2.3 msgrcv 2.2.4 msgctl 2.2.5 代码示例 2.3 信号量数组 2.3.1 semget 2.3.2 semop 2.3.3 semctl 2.3.4 代码示例 2.3 共享内存 2.3.1 shmget…

服务器如何做好入侵防护

不管是企业还是个人&#xff0c;网上业务都需要依赖于服务器&#xff0c;服务器一旦被黑客入侵&#xff0c;企业会面临很多安全风险&#xff0c;比如业务被中断、数据被窃取、被加密勒索、服务器不稳定等影响。入侵防护&#xff0c;主机安全也是目前网络安全防护的一个重点。关…

碳酸氢锂/硫酸锂溶液纯化除钙镁解决方案

碳酸锂是锂电行业阳极生产中的一个重要原材料&#xff0c;主要用于制造钴酸锂、镍酸锂、锰酸锂等电极材料&#xff0c;也用于充电 锂电池中作非水溶液电解质等&#xff0c;具有良好的电化学性能&#xff0c;应用领域还在不断扩大。工业级碳酸锂主含量&#xff08;Li2CO3&#x…

idea创建spring boot项目,java版本只能选择17和21

1.问题描述 java版本为"11.0.20"&#xff0c;idea2023创建spring boot项目时&#xff08;File->Project->Spring Initializr&#xff09;&#xff0c;java版本无法选择11&#xff0c;导致报错&#xff0c;如下图所示&#xff1a; 2.原因 spring2.X版本在2023…

java设计模式学习之【抽象工厂模式】

文章目录 引言抽象工厂模式简介定义与用途实现方式&#xff1a; 使用场景优势与劣势抽象工厂模式在spring中的应用银行和贷款服务示例代码地址 引言 在我们之前的讨论中&#xff0c;我们探索了工厂方法模式——一种简化单一产品创建的设计模式。现在&#xff0c;我们将视角转向…

QT linux下应用程序打包

一、应用程序app 1、应用程序的pro文件 2、 程序工作函数 3、app的UI界面 二、动态库lib 1、Lib类头文件 2、.cpp文件 三、对应用程序和动态库进行构建 1、对动态库进行qmake,然后进行构建 2、对应用程序进行qmake&#xff0c;然后进行构建 3、查看构建目录 四、编写脚本 …

零基础学编程轻松学编程,分享一款中文编程工具,编程构件简介

零基础学编程轻松学编程&#xff0c;分享一款中文编程工具&#xff0c;编程构件简介 中文编程开发语言工具编辑区界面截图如上图。 给大家分享一款中文编程工具 零基础轻松学编程&#xff0c;不需英语基础&#xff0c;编程工具可下载。 这款工具不但可以连接部分硬件&#…

Mac苹果视频剪辑:Final Cut Pro Mac

Final Cut Pro是一款由Apple公司开发的专业视频非线性编辑软件&#xff0c;是业界著名的视频剪辑软件之一。它最初发布于1999年&#xff0c;是Mac电脑上的一款独占软件。Final Cut Pro具有先进的剪辑工具、丰富的特效和颜色分级、音频处理等功能&#xff0c;使得用户可以轻松地…