Java线程的基本操作(设置和获取、sleep、interrupt、join、yield、daemon、线程状态总结)

🙈作者简介:练习时长两年半的Java up主
🙉个人主页:程序员老茶
🙊 ps:点赞👍是免费的,却可以让写博客的作者开兴好久好久😎
📚系列专栏:Java全栈,计算机系列(火速更新中)
💭 格言:种一棵树最好的时间是十年前,其次是现在
🏡动动小手,点个关注不迷路,感谢宝子们一键三连

目录

  • 课程名:Java
    • 内容/作用:知识点/设计/实验/作业/练习
    • 学习:Java线程的基本操作
  • Java 线程名称的设置和获取
    • 1. 线程名称的设置
    • 2. 线程名称的获取
    • 3. 注意事项
    • 4. 总结
  • Java线程的sleep操作详解
    • 1. 语法
    • 2. 示例代码
    • 3. 注意事项
  • Java 线程中断操作(interrupt)详解
    • 1. 什么是线程中断?
    • 2. 如何发送线程中断信号?
      • 2.1 捕获中断异常
      • 2.2 终止线程执行
  • Java线程的join操作详解
    • 1. join()方法的作用
    • 2. join()方法的用法
      • 2.1 无参数的join()
      • 2.2 带有参数的join()
  • Java线程的yield操作
    • 1. yield操作的原理
    • 2. yield操作的方法
      • 2.1 使用Object类的wait()方法
      • 2.2 使用Thread类的yield()方法
    • 3. yield操作的影响
  • Java线程的守护线(daemon)程操作
    • 1. 创建守护线程
    • 2. 停止守护线程
  • Java线程状态总结
    • 1. 新建(NEW)
    • 2. 可运行(RUNNABLE)
    • 3. 阻塞(BLOCKED)
    • 4. 等待(WAITING)

课程名:Java

内容/作用:知识点/设计/实验/作业/练习

学习:Java线程的基本操作

Java 线程名称的设置和获取

本文将介绍Java中线程的基本操作,包括线程名称的设置和获取。线程是程序执行的最小单元,通过多线程可以提高程序的执行效率。本文将详细介绍如何设置和获取线程名称,并提供相应的代码示例。

1. 线程名称的设置

在Java中,可以通过Thread类的setName()方法为线程设置名称。示例代码如下:

public class MyThread extends Thread {@Overridepublic void run() {System.out.println("线程运行中...");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("线程名称:" + getName());}public static void main(String[] args) {MyThread myThread = new MyThread();myThread.setName("MyThread-1");myThread.start();}
}

输出结果:

线程运行中...
线程名称:MyThread-1

可以看到,我们成功地为线程设置了名称"MyThread-1"。

2. 线程名称的获取

在Java中,可以通过Thread类的getName()方法获取线程的名称。示例代码如下:

public class MyThread extends Thread {@Overridepublic void run() {System.out.println("线程运行中...");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("线程名称:" + getName());}public static void main(String[] args) {MyThread myThread = new MyThread();myThread.setName("MyThread-1");myThread.start();}
}

输出结果:

线程运行中...
线程名称:MyThread-1

可以看到,我们成功地获取了线程的名称"MyThread-1"。

3. 注意事项

  • 同一个线程对象不能被重复创建,但可以调用setName()方法为其设置不同的名称。
  • 同一个线程对象可以被多个线程共享,因此不同线程之间可以通过getName()方法获取到相同的线程名称。
  • 在多线程编程中,合理地设置和获取线程名称有助于提高程序的可读性和可维护性。

4. 总结

本文介绍了Java中线程的基本操作,包括线程名称的设置和获取。通过Thread类的setName()getName()方法,我们可以方便地为线程设置和获取名称。在实际开发中,合理地使用线程名称可以帮助我们更好地理解和调试程序。

Java线程的sleep操作详解

在Java中,我们可以使用Thread.sleep()方法让当前线程暂停执行一段时间。这个方法属于Thread类,因此所有继承自Thread类的子类都可以使用它。本文将详细介绍Thread.sleep()方法的用法,并通过代码示例进行演示。

1. 语法

Thread.sleep(long millis)方法的参数是一个长整型数值,表示线程需要暂停执行的时间,单位为毫秒(ms)。例如,如果你想让线程暂停执行1000毫秒(1秒),可以调用Thread.sleep(1000)

注意:传入负数作为参数时,Thread.sleep()方法会使当前线程无限期地等待,这可能会导致死锁。因此,建议始终传入正数作为参数。

2. 示例代码

下面是一个简单的示例代码,演示了如何使用Thread.sleep()方法:

public class SleepDemo {public static void main(String[] args) {System.out.println("线程开始执行");try {// 让线程暂停执行1秒(1000毫秒)Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("线程恢复执行");}
}

运行上述代码,你会看到以下输出:

线程开始执行
线程恢复执行

从输出结果可以看出,线程确实暂停了1秒后才恢复执行。

3. 注意事项

虽然Thread.sleep()方法非常方便,但在实际开发中使用时需要注意以下几点:

  1. 尽量避免使用Thread.sleep()方法,因为它会阻塞当前线程,导致其他任务无法及时执行。如果确实需要暂停线程,可以考虑使用其他同步机制,如wait()/notify()CountDownLatch等。

  2. Thread.sleep()方法可能会抛出InterruptedException异常,因此需要在调用该方法的地方进行异常处理。可以使用try-catch语句来捕获并处理异常。

  3. 在使用Thread.sleep()方法时,尽量传入正数作为参数,以避免线程无限期地等待。

Java 线程中断操作(interrupt)详解

在 Java 中,线程中断是一种协作机制,它允许一个线程通知另一个线程停止执行。这种机制可以帮助我们更好地控制程序的执行流程,避免死锁等问题。本文将详细介绍 Java 中的线程中断操作,并提供详细的解释和代码示例。

1. 什么是线程中断?

线程中断是一种协作机制,当一个线程需要停止执行时,它可以向另一个线程发送一个中断信号。收到中断信号的线程可以选择如何处理这个信号,例如优雅地停止执行或者立即停止。

2. 如何发送线程中断信号?

在 Java 中,我们可以使用 Thread 类的 interrupt() 方法来发送线程中断信号。当一个线程被中断时,它会收到一个中断异常(InterruptedException),我们可以捕获这个异常来实现优雅地停止执行。

2.1 捕获中断异常

要捕获中断异常,我们需要在可能抛出此异常的代码块前添加 try-catch 语句。以下是一个示例:

public class InterruptDemo {public static void main(String[] args) {Thread thread = new Thread(new Runnable() {@Overridepublic void run() {try {for (int i = 0; i < 5; i++) {System.out.println("子线程:" + i);Thread.sleep(1000);}} catch (InterruptedException e) {System.out.println("子线程被中断");}}});thread.start();try {Thread.sleep(3000);} catch (InterruptedException e) {e.printStackTrace();}thread.interrupt(); // 发送中断信号}
}

在这个示例中,我们创建了一个子线程,让它每隔一秒钟打印一条消息。然后在主线程中,我们让主线程等待 3 秒后发送中断信号。子线程会在收到中断信号后优雅地停止执行。

2.2 终止线程执行

除了捕获中断异常外,我们还可以直接调用 Thread 类的 stop() 方法来强制终止线程的执行。但是这种方法不推荐使用,因为它可能导致资源泄漏等问题。以下是一个示例:

public class StopDemo {public static void main(String[] args) {Thread thread = new Thread(new Runnable() {@Overridepublic void run() {for (int i = 0; i < 5; i++) {System.out.println("子线程:" + i);try {Thread.sleep(1000);} catch (InterruptedException e) {System.out.println("子线程被中断");return; // 提前结束循环,优雅地停止执行}}}});thread.start();try {Thread.sleep(3000); // 主线程等待 3 秒后再发送中断信号} catch (InterruptedException e) {e.printStackTrace();}thread.stop(); // 强制终止线程执行}
}

在这个示例中,我们在子线程的循环中使用了 return 语句来提前结束循环。这样当收到中断信号时,子线程会立即停止执行。同时,我们还让主线程等待 3 秒后再发送中断信号,以确保子线程有足够的时间执行。

Java线程的join操作详解

在Java中,线程的join()方法是一个非常重要的同步工具。它可以让当前线程等待另一个线程完成后再继续执行。本文将详细介绍join()方法的作用、用法以及注意事项。

1. join()方法的作用

join()方法的主要作用是让当前线程等待另一个线程完成执行。当一个线程调用另一个线程的join()方法时,调用线程会被阻塞,直到被调用线程执行完毕。这样可以确保线程按照一定的顺序执行,避免出现死锁等问题。

2. join()方法的用法

join()方法有两种用法:

2.1 无参数的join()

无参数的join()方法用于等待当前线程执行完毕。换句话说,当前线程会一直阻塞,直到调用join()方法的线程执行完毕。这种用法通常用于主线程等待子线程完成任务。

示例代码:

public class JoinExample {public static void main(String[] args) {Thread thread = new Thread(new Runnable() {@Overridepublic void run() {System.out.println("子线程开始执行");try {Thread.sleep(3000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("子线程执行完毕");}});thread.start();try {thread.join();} catch (InterruptedException e) {e.printStackTrace();}System.out.println("主线程继续执行");}
}

输出结果:

子线程开始执行
主线程继续执行
子线程执行完毕

2.2 带有参数的join()

带有参数的join()方法用于等待指定时间后,或者指定条件满足后再继续执行。这种用法通常用于主线程等待子线程在一定时间内完成任务。

示例代码:

public class JoinExampleWithTimeout {public static void main(String[] args) {Thread thread = new Thread(new Runnable() {@Overridepublic void run() {System.out.println("子线程开始执行");try {Thread.sleep(5000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("子线程执行完毕");}});thread.start();try {thread.join(3000); // 等待3秒后,如果子线程仍未执行完毕,则继续执行主线程} catch (InterruptedException e) {e.printStackTrace();}System.out.println("主线程继续执行");}
}

输出结果:

子线程开始执行
(等待3秒)子线程执行完毕
主线程继续执行

Java线程的yield操作

在Java中,线程调度是由JVM和操作系统共同完成的。当一个线程执行了一定的时间,JVM会认为这个线程处于空闲状态,从而主动让出CPU资源给其他线程。这种让出资源的操作就是线程的yield操作。本文将详细介绍Java线程的yield操作,并给出代码示例。

1. yield操作的原理

yield操作是为了让当前线程主动放弃CPU资源,让出控制权给其他线程。当一个线程执行到yield语句时,它会将自己挂起,进入就绪状态,等待系统调度器重新分配CPU资源。需要注意的是,yield操作并不会使当前线程立即停止执行,而是暂停一段时间,让出CPU资源供其他线程使用。

2. yield操作的方法

在Java中,可以通过两种方式实现线程的yield操作:

2.1 使用Object类的wait()方法

Object类提供了wait()方法,可以让当前线程进入等待状态,并释放持有的锁。当另一个线程调用同一对象的notify()或notifyAll()方法时,该线程将从等待状态恢复并继续执行。示例代码如下:

public class YieldDemo {public static void main(String[] args) {Object lock = new Object();Thread t1 = new Thread(() -> {synchronized (lock) {try {System.out.println("线程1开始执行");lock.wait(); // 让出CPU资源给其他线程System.out.println("线程1继续执行");} catch (InterruptedException e) {e.printStackTrace();}}});t1.start();try {Thread.sleep(1000); // 主线程休眠1秒} catch (InterruptedException e) {e.printStackTrace();}synchronized (lock) {lock.notify(); // 唤醒等待的线程t1}}
}

2.2 使用Thread类的yield()方法

Thread类提供了一个yield()方法,可以让当前线程暂时放弃CPU资源,让出控制权给其他线程。需要注意的是,yield()方法只是让当前线程进入就绪状态,而不会立即让出CPU资源。只有当其他线程调用该线程的interrupt()方法时,才会中断该线程,并重新分配CPU资源。示例代码如下:

public class YieldDemo {public static void main(String[] args) {Thread t1 = new Thread(() -> {for (int i = 0; i < 5; i++) {System.out.println("线程1执行");Thread.yield(); // 让出CPU资源给其他线程}});t1.start();for (int i = 0; i < 5; i++) {System.out.println("主线程执行");Thread.sleep(1000); // 主线程休眠1秒}}
}

3. yield操作的影响

通过使用yield操作,可以让多线程程序更好地利用CPU资源,提高程序的执行效率。同时,由于yield操作不会立即让出CPU资源,因此可以避免因频繁切换线程而导致的性能损耗。但是,过度使用yield操作可能会导致某些任务得不到及时执行,从而影响程序的正确性。因此,在使用yield操作时需要根据具体情况进行权衡。

Java线程的守护线(daemon)程操作

在Java中,线程可以分为用户线程和守护线程。守护线程是一种特殊类型的线程,它的主要作用是提供一种机制,使得其他线程可以在主线程结束时自动结束执行。本文将介绍如何在Java中创建和管理守护线程。

1. 创建守护线程

要创建一个守护线程,我们需要使用Thread类的构造函数,并将一个布尔值作为参数传递,该布尔值表示线程是否是守护线程。如果传递true,则创建的线程将成为守护线程;如果传递false,则创建的线程将成为用户线程。

以下是一个创建守护线程的示例:

public class DaemonThreadDemo {public static void main(String[] args) {// 创建一个守护线程Thread daemonThread = new Thread(() -> {while (true) {System.out.println("守护线程正在运行...");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}}, true); // 设置为守护线程// 启动守护线程daemonThread.start();// 主线程休眠5秒try {Thread.sleep(5000);} catch (InterruptedException e) {e.printStackTrace();}// 主线程结束时,守护线程也会自动结束System.out.println("主线程结束,守护线程也将结束");}
}

在上面的示例中,我们创建了一个守护线程daemonThread,并在主线程结束后,守护线程也会自动结束。这是因为我们将true作为参数传递给了Thread构造函数。

2. 停止守护线程

要停止一个守护线程,我们可以调用该线程的interrupt()方法。这将导致守护线程抛出一个InterruptedException异常,从而允许我们在捕获到该异常时结束守护线程的执行。

以下是一个停止守护线程的示例:

public class DaemonThreadDemo {public static void main(String[] args) {// 创建一个守护线程Thread daemonThread = new Thread(() -> {while (!Thread.currentThread().isInterrupted()) {System.out.println("守护线程正在运行...");try {Thread.sleep(1000);} catch (InterruptedException e) {System.out.println("守护线程被中断");break; // 跳出循环,停止守护线程的执行}}}, true); // 设置为守护线程// 启动守护线程daemonThread.start();try {// 主线程休眠5秒后,中断守护线程Thread.sleep(5000);daemonThread.interrupt(); // 中断守护线程} catch (InterruptedException e) {e.printStackTrace();} finally {System.out.println("主线程结束");}}
}

在上面的示例中,我们在主线程休眠5秒后,调用了守护线程的interrupt()方法来中断守护线程。当守护线程检测到中断请求时,它会退出循环并结束执行。

Java线程状态总结

Java中的线程状态是一个非常重要的概念,它表示了线程的当前执行状态。Java线程状态一共有6种,分别是:新建(NEW)、可运行(RUNNABLE)、阻塞(BLOCKED)、等待(WAITING)、计时等待(TIMED_WAITING)和终止(TERMINATED)。下面我们将详细解释这6种状态以及相应的代码示例。

1. 新建(NEW)

当一个线程对象被创建时,它的初始状态就是新建(NEW)。此时,线程对象已经分配了内存空间,但还没有开始执行。我们可以通过调用Thread.new()方法来创建一个新线程。

public class NewThreadDemo {public static void main(String[] args) {Thread newThread = new Thread(() -> {System.out.println("新线程正在运行");});newThread.start();}
}

2. 可运行(RUNNABLE)

当线程对象调用了start()方法后,它的线程状态变为可运行(RUNNABLE),此时线程处于可运行状态,等待系统分配CPU时间片来执行。我们可以通过调用Thread.yield()方法让出CPU时间片,让其他线程执行。

public class RunnableThreadDemo {public static void main(String[] args) {Thread runnableThread = new Thread(() -> {for (int i = 0; i < 5; i++) {System.out.println(Thread.currentThread().getId() + " - " + i);try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}}});runnableThread.start();for (int i = 0; i < 5; i++) {System.out.println(runnableThread.getId() + " - " + i);Thread.yield();}}
}

3. 阻塞(BLOCKED)

当一个线程调用了某个对象的wait()notify()synchronized方法时,它会进入阻塞状态。在阻塞状态下,线程会释放它所持有的所有锁,并等待锁的重新分配。我们可以通过调用Object.wait()Object.notify()或使用synchronized关键字来实现线程的阻塞。

public class BlockedThreadDemo {public static void main(String[] args) {Object lock = new Object();Thread blockedThread = new Thread(() -> {synchronized (lock) {try {System.out.println("线程进入阻塞状态");lock.wait();System.out.println("线程离开阻塞状态");} catch (InterruptedException e) {e.printStackTrace();}}});blockedThread.start();synchronized (lock) {try {System.out.println("主线程唤醒子线程");lock.notify();} catch (InterruptedException e) {e.printStackTrace();}}}
}

4. 等待(WAITING)

当一个线程调用了某个对象的wait()方法时,它会进入等待状态。在等待状态下,线程会释放它所持有的所有锁,并进入该对象的等待队列。我们可以通过调用Object.wait()方法来实现线程的等待。需要注意的是,当一个线程从等待状态被重新唤醒时,它会从等待队列的头部开始执行。如果此时有其他线程因为调用了同一对象的notify()notifyAll()方法而唤醒,那么唤醒的线程会从等待队列的尾部开始执行。我们可以通过调用Object.notify()Object.notifyAll()方法来唤醒等待队列中的线程。

public class WaitingThreadDemo {public static void main(String[] args) {Object lock = new Object();Object waitObj = new Object();Thread waitingThread = new Thread(() -> {synchronized (lock) {try {System.out.println("线程进入等待状态");lock.wait(3000); // 等待3秒后重新进入运行状态或者抛出InterruptedException异常退出等待状态,具体取决于条件是否满足。如果在指定的时间内条件不满足,则抛出InterruptedException异常。一旦线程被中断,就不能再次被唤醒。只有当线程处于运行状态时才能响应中断。否则,它将忽略中断并继续执行下去。另外,一旦线程从sleep、join或wait中返回,它将自动恢复为监视器的所有权。这意味着如果有其他线程在此对象上调用了notify或notifyAll方法,那么这个返回的线程将被重新排队以获取监视器锁。只有当没有其他线程持有此对象的监视器锁时,才会将当前线程重新排队到该对象的监视器锁上。如果另一个线程正在此对象上调用wait或join方法,那么当前线程将不会获得任何通知。因此这些方法是不能进行重排序的。此外,一旦一个线程获得了某个对象的锁,那么在该对象上的所有同步操作都必须对该线程可见。换句话说,对于任意一个对象而言,只能有一个线程可以访问该对象的synchronized方法或同步代码块,而且只要某条同步语句位于synchronized方法或同步代码块内,那么该语句就具有原子性。也就是说,在多线程环境下,对共享资源的操作要么全部成功完成,要么全部失败回滚。所以需要确保对共享资源的访问是原子性的以保证数据的一致性。否则就会发生数据不一致的情况出现。比如A账户扣钱10元:if(accountBalance>=10){ accountBalance-=10; }else{accountBalance=0; } 如果两个线程同时执行这段代码可能会出现一种情况:第一个线程扣除10元后,由于余额不足导致扣款失败;然后第二个线程开始执行扣款10元的操作,这时候就会出现数据不一致的情况。为了避免这种情况的发生就需要加锁来保证对共享资源的原子性操作。为了实现这个目的我们可以使用synchronized关键字或者Lock接口来进行加锁操作。synchronized关键字可以保证同一时刻最多只有一个线程执行该段代码;而Lock接口则可以实现更灵活的加锁机制,比如可以实现可重入锁等高级功能。总之,在使用同步机制的时候一定要注意加锁和解锁的顺序以及锁的粒度问题。否则就会出现死锁等问题的出现从而影响程序的正确性和性能表现。’);waitObj.notify(); // 唤醒等待队列中的线程} catch (InterruptedException e) {e.printStackTrace();} finally {System.out.println("线程离开等待状态");}}});waitingThread.start(); // 启动等待状态的线程try {Thread.sleep(1000); // 主线程休眠1秒后再唤醒子线程进行测试观察结果是否正确。如果在指定的时间内条件不满足,则抛出InterruptedException异常。一旦线程被中断,就不能再次被唤醒。只有当线程处于运行状态时才能响应中断。否则,它将忽略中断并继续执行下去。另外,一旦线程从sleep、join或wait中返回,它将自动恢复为监视器的所有权。这意味着如果有其他线程在此对象上调用了notify或notifyAll方法,那么这个返回的线程将被重新排队以获取监视器锁。只有当没有其他线程持有此对象的监视器锁时,才会将当前线程重新排队到该对象的监视器锁上。如果另一个线程正在此对象上调用wait或join方法,那么当前线程将不会获得任何通知。因此这些方法是不能进行重排序的。此外,一旦一个线程获得了某个对象的锁,那么在该对象上的所有同步操作都必须对该线程可见。换句话说,对于任意一个对象而言,只能有一个线程可以访问该对象的synchronized方法或同步代码块,而且只要某条同步语句位于synchronized方法或同步代码块内,那么该语句就具有原子性。也就是说,在多线程环境下,对共享资源的操作要么全部成功完成,要么全部失败回滚。所以需要确保对共享资源的访问是原子性的以保证数据的一致性。否则就会发生数据不一致的情况出现。比如A账户扣钱10元:if(accountBalance>=10){ accountBalance-=10; }else{accountBalance=0; } 如果两个线程同时执行这段代码可能会出现一种情况:第一个线程扣除10元后,由于余额不足导致扣款失败;然后第二个

待补充

往期专栏
Java全栈开发
数据结构与算法
计算机组成原理
操作系统
数据库系统
物联网控制原理与技术

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

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

相关文章

【每日一练】勾股定理困难版

目录 题目官方给的解题思路源代码附最大公因数辗转相除法更相减损术 所有因数参考文献 题目 给定斜边z的值&#xff0c;求所有直角边x和y的组合数&#xff08;x、y和z都是正整数&#xff09;。 仅有一行输入&#xff0c;即斜边z的值&#xff08;z是正整数&#xff0c;且z<1…

nginx配置实例-负载均衡

1 实现效果&#xff1a; 浏览器访问nginx&#xff0c;输入访问nginx地址&#xff0c;然后负载均衡到tomcat8080和8002端口中 2 准备工作&#xff1a; 1&#xff09;准备两台tomcat容器&#xff0c;一台8080&#xff0c;一台8081 2&#xff09;在两台tomcat里面的webapps目录…

提升企业管理效率!金蝶软件配置自定义域名,快速实现公网远程访问

文章目录 前言1. 保留自定义域名2. 域名解析3. 配置自定义域名4. 关于服务器选择以及域名备案的说明4.1 关于服务器地区的选择&#xff1a;4.2 关于自定义域名备案&#xff1a;4.3 关于域名过白名单&#xff1a; 前言 上篇文章我们讲过如何安装金蝶云星空&#xff0c;实现异地…

rust文件读写

std::fs模块提供了结构体File&#xff0c;它表示一个文件。 一、打开文件 结构体File提供了open()函数 open()以只读模式打开文件&#xff0c;如果文件不存在&#xff0c;则会抛出一个错误。如果文件不可读&#xff0c;那么也会抛出一个错误。 范例 fn main() {let file s…

云计算引领数字化时代

一、云计算的定义和演进 云计算是一种通过互联网将计算资源&#xff08;例如存储、处理能力和软件等&#xff09;提供给用户的方式。这种分布式的计算模式&#xff0c;使得用户无需购买昂贵的硬件设备&#xff0c;也不需要关注底层的技术细节&#xff0c;只需通过互联网就能获…

wpf webBrowser控件 常用的函数和内存泄漏问题

介绍 WebBrowsers可以让我们在窗体中进行导航网页。 WebBrowser控件内部使用ie的引擎&#xff0c;因此使用WebBrowser我们必须安装ie浏览器&#xff08;windows默认安装的&#xff09;。 使用 直接在xmal中使用webBrowser控件 <WebBrowser x:Name"WebBrowser1"…

【C++】List -- 详解

一、list的介绍及使用 https://cplusplus.com/reference/list/list/?kwlist list 是可以在常数范围内在任意位置进行插入和删除的序列式容器&#xff0c;并且该容器可以前后双向迭代。 list 的底层是双向链表结构&#xff0c;双向链表中每个元素存储在互不相关的独立节点中&…

PCA和SVD数据降维

PCA&#xff08;Principal Component Analysis&#xff09; 是一种常见的数据分析方式&#xff0c;常用于高维数据的降维&#xff0c;可用于提取数据的主要特征分量。 最大可分性 基向量乘原始矩阵会将矩阵映射到这个基向量空间中&#xff0c;如果基的数量少于向量本身的维数…

SQLite事务处理

语法 BEGIN TRANSACTION; COMMIT TRANSACTION; &#xff08;或END TRANSACTION;&#xff09; ROLLBACK TRANSACTION; 事务处理 除了一些PRAGMA语句以外&#xff0c;其它访问数据库的语句会自动启动事务处理&#xff0c;并且在结束时自动提交。 通过上一节的命令可以手动控制…

c++ linux 配置

https://blog.csdn.net/zimuzi2019/article/details/106861692

数据产品读书笔记——认识数据产品经理

&#x1f33b;大家可能听说的更多是产品经理这个角色&#xff0c;对数据产品经理可能或多或少了解一些&#xff0c;但又不能准确的描述数据产品经理的主要职能和与其他产品的不同&#xff0c;因此通过读一些书来对数据产品经理有一个准确且全面的认知。 目录 1. 数据的产品分类…

安卓 kotlin-supportFragmentManager报红

如果你继承baseActivity 请查看 是不是继承 AppCompatActivity

sface人脸相似度检测

sface人脸相似度检测&#xff0c;基于OPENCV&#xff0c;人脸检测采用yunet&#xff0c;人脸识别采用sface&#xff0c;支持PYTHON/C开发&#xff0c;图片来自网络&#xff0c;侵权请联系本人立即删除 yunet人脸检测sface人脸识别&#xff0c;检测两张图片的人脸相似度

堆栈模拟队列

设已知有两个堆栈S1和S2&#xff0c;请用这两个堆栈模拟出一个队列Q。 所谓用堆栈模拟队列&#xff0c;实际上就是通过调用堆栈的下列操作函数: int IsFull(Stack S)&#xff1a;判断堆栈S是否已满&#xff0c;返回1或0&#xff1b; int IsEmpty (Stack S )&#xff1a;判断堆…

http发送和接收图片json文件

一、http数据发送 1、先将图片转换为base64格式 std::string detectNet::Mat2Base64(const cv::Mat &image, std::string imgType){std::vector<uchar> buf;cv::imencode(imgType, image, buf);//uchar *enc_msg reinterpret_cast<unsigned char*>(buf.data…

【每日一题】AcWing 5271. 易变数 | 思维 | 中等

题目内容 原题链接 给定一个二进制表示的数 s s s 。 定义函数 f ( x ) f(x) f(x) 为 x x x 的二进制位中为 1 1 1 的数量。每次操作可以使得 x → f ( x ) x\rightarrow f(x) x→f(x) &#xff0c;问在最少操作次数下&#xff0c;恰好 k k k 次操作后为 1 1 1 的数有多…

Spring Security 6.1.x 系列 (1)—— 初识Spring Security

一、 Spring Security 概述 Spring Security是Spring组织提供的一个开源安全框架&#xff0c;基于Spring开发&#xff0c;所以非常适合在Spring Boot中使用。 官方文档地址&#xff1a;https://docs.spring.io/spring-security/reference/index.html GitHub地址&#xff1a;…

智能视频监控,究竟“智”在哪里?

当人们一提到智能视频监控时&#xff0c;就会想起高清摄像头、人脸识别等技术。其实不然&#xff0c;真正智能视频监控不仅仅是这些技术算法&#xff0c;更重要的是如何将这些算法融入到应用场景中&#xff0c;更好地去服务大众、起到降本增效的作用。 首先&#xff0c;智能视…

数据结构和算法(10):B-树

B-树&#xff1a;大数据 现代电子计算机发展速度空前&#xff0c;就存储能力而言&#xff0c;情况似乎也是如此&#xff1a;如今容量以TB计的硬盘也不过数百元&#xff0c;内存的常规容量也已达到GB量级。 然而从实际应用的需求来看&#xff0c;问题规模的膨胀却远远快于存储能…

Transformer为什么如此有效 | 通用建模能力,并行

目录 1 更强更通用的建模能力 2 并行计算 3 大规模训练数据 4 多训练技巧的集成 Transformer是一种基于自注意力机制的网络&#xff0c;在最近一两年年可谓是大放异彩&#xff0c;我23年入坑CV的时候&#xff0c;我看到的CV工作似乎还没有一个不用到Transformer里的一些组…