Java学习笔记(十五)

news2024/11/22 0:08:33

wait()

在Java的并发编程中,wait方法是实现线程间通信和协作的重要机制之一。它属于Object类的方法,通常与notifynotifyAll方法一起使用,以实现线程间的同步和协作。以下是对JUC(Java Utility Concurrency)中wait方法的详细介绍,内容将涵盖其定义、工作原理、使用场景、注意事项以及与其他并发机制的比较等方面。

一、wait方法的定义与功能

wait方法是Object类中的一个本地方法,用于使当前线程等待,直到其他线程调用同一个对象的notifynotifyAll方法来唤醒它。wait方法有几个重载版本,分别如下:

  1. void wait():使当前线程无限期地等待,直到其他线程调用此对象的notifynotifyAll方法。调用此方法后,当前线程会释放它持有的对象锁,并进入等待状态。
  2. void wait(long timeout):使当前线程等待指定的时间(以毫秒为单位),直到其他线程调用此对象的notifynotifyAll方法,或者指定的时间已过。如果在等待期间被唤醒或时间到期,线程将重新获得锁并继续执行。
  3. void wait(long timeout, int nanos):使当前线程等待指定的时间(以毫秒和纳秒为单位),直到其他线程调用此对象的notifynotifyAll方法,或者指定的时间已过。这个方法提供了更高的时间精度。

需要注意的是,wait方法必须在同步块或同步方法中调用,否则会抛出IllegalMonitorStateException异常。调用wait方法后,当前线程会释放对象的锁,但不会释放对象的所有权。

二、wait方法的工作原理

wait方法的工作原理与Java的内存模型和线程状态密切相关。在Java中,线程的状态包括新建(NEW)、就绪(READY)、运行(RUNNING)、阻塞(BLOCKED)、等待(WAITING)、超时等待(TIMED_WAITING)和终止(TERMINATED)等。

当线程调用wait方法时,它会进入等待状态(WAITING或TIMED_WAITING,取决于是否指定了超时时间)。在等待状态下,线程不会占用CPU资源,也不会执行任何操作,直到被其他线程唤醒或超时时间到达。

唤醒线程的方式有两种:

  1. 其他线程调用同一个对象的notify方法,唤醒一个等待状态的线程(如果有多个线程在等待,则选择其中一个)。
  2. 其他线程调用同一个对象的notifyAll方法,唤醒所有等待状态的线程。

当线程被唤醒后,它不会立即获得锁并继续执行。相反,它会重新进入就绪状态(READY),并等待机会重新获得锁。一旦获得锁,线程将继续执行wait方法之后的代码。

三、wait方法的使用场景

wait方法通常用于线程间的协作和通信,特别是在需要等待某个条件成立时。以下是一些常见的使用场景:

  1. 生产者-消费者问题:在生产者-消费者模式中,生产者线程负责生成数据并将其放入缓冲区,而消费者线程负责从缓冲区中取出数据并处理。在这种情况下,可以使用waitnotify方法来实现生产者和消费者之间的同步和协作。例如,当缓冲区为空时,消费者线程可以调用wait方法等待;当生产者线程向缓冲区添加数据后,可以调用notify方法来唤醒等待的消费者线程。
  2. 线程池中的任务等待:在线程池中,如果任务队列已满且没有可用的线程来处理新任务,那么新任务可能需要等待。在这种情况下,可以使用wait方法使等待线程进入等待状态,并在有空闲线程或任务队列有空间时通过notifynotifyAll方法唤醒它们。
  3. 其他需要线程等待的场景:除了上述两种场景外,wait方法还可以用于其他需要线程等待的场景,如等待某个资源变得可用、等待某个事件发生等。

四、使用wait方法时的注意事项

在使用wait方法时,需要注意以下几点:

  1. 必须在同步块或同步方法中调用:由于wait方法会释放对象的锁,因此它必须在同步块或同步方法中调用。否则,会抛出IllegalMonitorStateException异常。
  2. 避免死锁:在使用waitnotify方法时,需要确保不会导致死锁。例如,如果线程A在等待线程B的通知,而线程B又在等待线程A的通知,那么这两个线程将永远无法继续执行。为了避免这种情况,可以使用其他同步机制(如条件变量、信号量等)或确保线程之间的等待和通知是单向的。
  3. 处理中断异常wait方法可能会抛出InterruptedException异常,这通常发生在等待期间线程被中断时。因此,在使用wait方法时,需要捕获并处理这个异常。如果不需要处理中断,可以选择将异常抛出给上层调用者处理。
  4. 避免忙等待:在使用wait方法时,应避免使用忙等待(busy waiting)来检查条件是否成立。忙等待会浪费CPU资源,并可能导致性能问题。相反,应该使用wait方法等待条件成立,并在条件成立时被唤醒。
  5. 注意notifynotifyAll的区别notify方法只会唤醒一个等待的线程,而notifyAll方法会唤醒所有等待的线程。在选择使用哪个方法时,需要根据具体场景来决定。如果只需要唤醒一个线程,则使用notify方法;如果需要唤醒所有线程,则使用notifyAll方法。

五、wait方法与其他并发机制的比较

在Java并发编程中,除了waitnotify方法外,还有其他一些并发机制可以用于实现线程间的同步和协作。以下是一些常见的并发机制及其与wait方法的比较:

  1. synchronized关键字synchronized关键字是Java中实现线程同步的基本机制之一。它可以通过修饰方法或代码块来确保同一时间只有一个线程可以执行被修饰的代码。与wait方法相比,synchronized关键字提供了一种更简单的同步方式,但它并不具备wait方法的等待和唤醒功能。
  2. Lock接口及其实现类Lock接口是Java 5中引入的一种新的锁机制,它提供了比synchronized关键字更灵活的锁控制。Lock接口的实现类(如ReentrantLock)提供了显式的锁获取和释放操作,以及支持条件变量(Condition)的等待和唤醒功能。与wait方法相比,使用Lock接口和条件变量可以提供更灵活的线程同步和协作机制。
  3. 信号量(Semaphore):信号量是一种用于控制多个线程对共享资源进行访问的并发机制。它允许一定数量的线程同时访问共享资源,并在资源不足时使其他线程等待。与wait方法相比,信号量提供了一种更细粒度的控制机制,可以限制同时访问共享资源的线程数量。
  4. 倒计时门栓(CountDownLatch):倒计时门栓是一种用于让一组线程等待直到另一个线程完成一系列操作的并发机制。它允许一个或多个线程等待直到倒计时结束,然后所有等待的线程可以继续执行。与wait方法相比,倒计时门栓提供了一种更简单的方式来等待一组操作的完成。

六、总结

wait方法是Java并发编程中实现线程间同步和协作的重要机制之一。它通过与notifynotifyAll方法的配合使用,可以实现线程间的等待和唤醒功能。在使用wait方法时,需要注意一些常见的注意事项,如必须在同步块或同步方法中调用、避免死锁、处理中断异常等。此外,还需要根据具体场景选择合适的并发机制来实现线程间的同步和协作。

尽管wait方法在某些场景下非常有用,但它也存在一些局限性。例如,它只能用于同步块或同步方法中的对象锁,无法与其他锁机制(如Lock接口)一起使用。此外,由于wait方法会释放对象的锁,因此在等待期间其他线程可以访问该对象的同步块或同步方法,这可能会导致数据不一致的问题。因此,在实际应用中,需要根据具体场景和需求选择合适的并发机制来实现线程间的同步和协作。

sleep()

在Java的并发编程中,sleep方法是Thread类中的一个静态方法,用于使当前执行的线程暂停执行指定的时间。这一方法对于控制线程的执行节奏、模拟延迟操作等场景非常有用。以下是对JUC(Java Utility Concurrency)中sleep方法的详细介绍,包括其定义、工作原理、使用场景、注意事项等。

一、sleep方法的定义与功能

sleep方法是Thread类中的一个静态方法,其签名如下:

public static void sleep(long millis) throws InterruptedException

或者带有纳秒参数的版本:

public static void sleep(long millis, int nanos) throws InterruptedException

其中,millis参数指定线程暂停执行的毫秒数,nanos参数指定额外的纳秒数(范围在0-999999之间)。需要注意的是,nanos参数的存在是为了提供比毫秒更精确的时间控制,但在实际使用中,由于线程调度的非实时性,这种精确性可能无法得到完全保证。

调用sleep方法后,当前线程会进入TIMED_WAITING状态,并放弃CPU资源,直到指定的时间到达或线程被中断。当时间到达或线程被中断时,线程会重新变为RUNNABLE状态,并等待CPU的调度来继续执行。

二、sleep方法的工作原理

sleep方法的工作原理与Java的内存模型和线程状态密切相关。在Java中,线程的状态包括新建(NEW)、就绪(READY)、运行(RUNNING)、阻塞(BLOCKED)、等待(WAITING)、超时等待(TIMED_WAITING)和终止(TERMINATED)等。

当线程调用sleep方法时,它会进入超时等待状态(TIMED_WAITING)。在这个状态下,线程不会占用CPU资源,也不会执行任何操作,直到指定的时间到达或线程被中断。如果线程在超时等待期间被中断,它会抛出一个InterruptedException异常,并立即退出超时等待状态。

需要注意的是,sleep方法并不会释放当前线程所持有的任何锁。这意味着,如果线程在持有锁的情况下调用sleep方法,那么其他线程仍然无法访问该锁保护的资源,直到当前线程从sleep方法中返回并释放锁。

三、sleep方法的使用场景

sleep方法在Java并发编程中有广泛的应用场景,以下是一些常见的使用场景:

  1. 模拟延迟操作:在某些情况下,我们可能需要模拟一些延迟操作,比如网络请求的响应时间、定时任务的执行间隔等。这时,可以使用sleep方法来使线程暂停执行指定的时间,从而模拟延迟效果。
  2. 控制线程执行节奏:在多线程编程中,有时需要控制线程的执行节奏,以避免某个线程过快地执行完任务而导致资源竞争或数据不一致等问题。通过调用sleep方法,可以使线程在执行过程中暂停一段时间,从而控制其执行节奏。
  3. 定时任务:在实现定时任务时,可以使用sleep方法来使线程在每次任务执行完毕后暂停一段时间,然后再执行下一次任务。这种方式虽然不如使用TimerScheduledExecutorService等定时任务框架精确和可靠,但在某些简单的场景下仍然是一种可行的选择。

四、使用sleep方法时的注意事项

在使用sleep方法时,需要注意以下几点:

  1. 处理中断异常sleep方法可能会抛出InterruptedException异常,这通常发生在等待期间线程被中断时。因此,在使用sleep方法时,需要捕获并处理这个异常。如果不需要处理中断,可以选择将异常抛出给上层调用者处理,或者在捕获异常后重新调用sleep方法以继续等待剩余的时间。但需要注意的是,重新调用sleep方法可能会导致总等待时间超过预期,因为重新调用时是从当前时间开始计算的。
  2. 避免死锁:虽然sleep方法不会释放线程所持有的锁,但在使用sleep方法时仍然需要注意避免死锁问题。例如,如果两个线程相互等待对方释放锁并调用sleep方法,那么这两个线程将永远无法继续执行。为了避免这种情况,需要确保线程之间的等待和释放锁的操作是合理的,并且不会出现循环等待的情况。
  3. 注意精度问题sleep方法的精度受到线程调度器的影响,因此在实际使用中可能无法完全保证指定的等待时间。特别是在多线程环境下,由于线程之间的竞争和调度的不确定性,实际等待时间可能会比预期的时间稍长或稍短。因此,在使用sleep方法时,需要考虑到这种精度问题,并根据实际情况进行调整。
  4. 避免忙等待:在使用sleep方法时,应避免使用忙等待(busy waiting)来检查条件是否成立。忙等待会浪费CPU资源,并可能导致性能问题。相反,应该使用sleep方法等待条件成立,并在条件成立时被唤醒。这样可以减少CPU的浪费,并提高系统的整体性能。

五、sleep方法与其他并发机制的比较

在Java并发编程中,除了sleep方法外,还有其他一些并发机制可以用于实现线程间的同步和协作。以下是一些常见的并发机制及其与sleep方法的比较:

  1. waitnotify方法waitnotify方法是Object类中的方法,用于实现线程间的等待和唤醒功能。与sleep方法相比,wait方法会释放当前线程所持有的锁,并允许其他线程访问该锁保护的资源。而sleep方法则不会释放锁。此外,wait方法需要在同步块或同步方法中调用,并且需要与其他线程通过共享对象进行通信。而sleep方法则可以在任何地方调用,并且不需要与其他线程进行通信。
  2. Lock接口及其实现类Lock接口是Java 5中引入的一种新的锁机制,它提供了比synchronized关键字更灵活的锁控制。与sleep方法相比,Lock接口及其实现类(如ReentrantLock)提供了显式的锁获取和释放操作,以及支持条件变量(Condition)的等待和唤醒功能。这使得Lock接口在实现复杂的线程同步和协作场景时更加灵活和强大。
  3. 信号量(Semaphore):信号量是一种用于控制多个线程对共享资源进行访问的并发机制。它允许一定数量的线程同时访问共享资源,并在资源不足时使其他线程等待。与sleep方法相比,信号量提供了一种更细粒度的控制机制,可以限制同时访问共享资源的线程数量。这使得信号量在实现资源池、连接池等场景时非常有用。
  4. 倒计时门栓(CountDownLatch):倒计时门栓是一种用于让一组线程等待直到另一个线程完成一系列操作的并发机制。它允许一个或多个线程等待直到倒计时结束,然后所有等待的线程可以继续执行。与sleep方法相比,倒计时门栓提供了一种更简单的方式来等待一组操作的完成。这使得倒计时门栓在实现并行计算、批量处理等场景时非常有用。

六、sleep方法的优化与替代方案

尽管sleep方法在Java并发编程中有广泛的应用场景,但它也存在一些局限性。例如,它无法提供精确的等待时间控制,也无法与其他锁机制(如Lock接口)进行良好的集成。因此,在实际应用中,有时需要考虑使用其他优化方案或替代方案来替代sleep方法。

  1. 使用TimeUnitTimeUnit类是Java中提供的一个用于时间单位转换和线程休眠的工具类。它提供了比Thread.sleep方法更可读和易用的休眠操作。通过使用TimeUnit类,可以更容易地指定休眠时间,并且不需要担心时间单位的转换问题。例如,可以使用TimeUnit.SECONDS.sleep(2)来替代Thread.sleep(2000),这样代码更加简洁和易读。
  2. 使用定时任务框架:对于需要定期执行的任务,可以使用Java提供的定时任务框架(如TimerScheduledExecutorService等)来替代sleep方法。这些框架提供了更精确和可靠的定时任务调度功能,并且可以处理任务的重复执行、异常处理等复杂场景。
  3. 使用条件变量(Condition):在实现复杂的线程同步和协作场景时,可以使用Lock接口中的条件变量(Condition)来替代waitnotify方法以及sleep方法。条件变量提供了更灵活和强大的等待和唤醒功能,并且可以与Lock接口进行良好的集成。这使得条件变量在实现复杂的线程同步和协作场景时更加可靠和高效。

七、总结

sleep方法是Java并发编程中实现线程暂停执行的重要机制之一。它可以使当前线程进入超时等待状态,并放弃CPU资源,直到指定的时间到达或线程被中断。尽管sleep方法在某些场景下非常有用,但它也存在一些局限性,如无法提供精确的等待时间控制、无法与其他锁机制进行良好的集成等。因此,在实际应用中,需要根据具体场景和需求选择合适的并发机制来实现线程间的同步和协作。同时,也需要注意sleep方法的使用注意事项和潜在问题,以确保代码的正确性和可靠性。

sleep() 和 wait() 区别

在Java多线程编程中,waitsleep是两个经常被使用的线程控制方法,尽管它们都能在一定程度上暂停线程的执行,但它们在实现机制、使用场景以及行为表现上存在着显著的差异。以下是对waitsleep方法的详细介绍和对比分析,旨在帮助读者深入理解这两个方法的不同之处。

一、定义与所属类

  1. sleep方法

    • 定义sleep是Java中Thread类的一个静态方法,它允许线程在指定的时间间隔内暂停执行。
    • 所属类:Thread类。
    • 方法签名public static void sleep(long millis) throws InterruptedExceptionpublic static void sleep(long millis, int nanos) throws InterruptedException
  2. wait方法

    • 定义wait是Java中Object类的一个实例方法,它用于让当前线程等待,直到其他线程调用该对象的notifynotifyAll方法。
    • 所属类:Object类。
    • 方法签名public final void wait() throws InterruptedExceptionpublic final void wait(long timeout) throws InterruptedException,或 public final void wait(long timeout, int nanos) throws InterruptedException

二、行为表现

  1. 锁释放

    • sleep方法sleep方法不会释放当前线程所持有的任何锁。即使线程在调用sleep方法后进入了休眠状态,它仍然持有之前获得的锁,这意味着其他线程无法访问被该锁保护的资源。
    • wait方法:与sleep方法不同,wait方法会释放当前线程所持有的锁。当线程调用wait方法时,它会进入等待状态,并释放之前获得的锁,从而允许其他线程访问被该锁保护的资源。
  2. 等待状态

    • sleep方法:调用sleep方法的线程会进入TIMED_WAITING状态,这是一种有时限的等待状态。当指定的等待时间到达时,线程会自动从TIMED_WAITING状态转变为RUNNABLE状态,并等待CPU的调度来继续执行。
    • wait方法:调用无参数的wait方法的线程会进入WAITING状态,这是一种无时限的等待状态。线程会一直等待,直到其他线程调用该对象的notifynotifyAll方法将其唤醒。如果调用了带有超时参数的wait方法,则线程会在指定的时间内等待,如果超时仍未被唤醒,则自动转变为RUNNABLE状态。
  3. 唤醒机制

    • sleep方法sleep方法不需要其他线程的干预,当指定的等待时间到达时,线程会自动从休眠状态中唤醒。
    • wait方法wait方法需要其他线程的干预才能被唤醒。具体来说,只有当其他线程调用了与当前线程等待对象相同的notifynotifyAll方法时,当前线程才会被唤醒。
  4. 异常处理

    • sleep方法sleep方法在调用时必须捕获InterruptedException异常。这个异常是在线程休眠期间被中断时抛出的。如果线程在休眠期间被中断,它会立即从休眠状态中退出,并抛出InterruptedException异常。
    • wait方法wait方法在调用时同样需要捕获InterruptedException异常。但与sleep方法不同的是,wait方法还可以响应对象的notifynotifyAll方法的调用,从而被唤醒并继续执行。

三、使用场景

  1. sleep方法的使用场景

    • 模拟延迟操作:在需要模拟一些延迟操作(如网络请求的响应时间、定时任务的执行间隔等)时,可以使用sleep方法。
    • 控制线程执行节奏:在多线程编程中,有时需要控制线程的执行节奏,以避免某个线程过快地执行完任务而导致资源竞争或数据不一致等问题。通过调用sleep方法,可以使线程在执行过程中暂停一段时间,从而控制其执行节奏。
  2. wait方法的使用场景

    • 线程间通信wait方法通常用于线程间的通信。当一个线程需要等待另一个线程完成某个任务时,可以使用wait方法让当前线程等待。而另一个线程在完成任务后,可以调用notifynotifyAll方法来唤醒等待的线程。
    • 解决生产者-消费者问题:在生产者-消费者问题中,生产者线程负责生产数据,并将其放入缓冲区;消费者线程负责从缓冲区中取出数据并进行处理。为了协调生产者和消费者的操作,可以使用waitnotify方法来实现线程间的同步和通信。

四、注意事项

  1. 避免死锁:在使用waitsleep方法时,都需要注意避免死锁问题。特别是当多个线程相互等待对方释放锁时,很容易导致死锁的发生。因此,需要确保线程之间的等待和释放锁的操作是合理的,并且不会出现循环等待的情况。
  2. 处理中断异常:无论是wait还是sleep方法,都需要捕获并处理InterruptedException异常。如果不需要处理中断,可以选择将异常抛出给上层调用者处理,或者在捕获异常后重新调用相应的方法以继续等待剩余的时间。但需要注意的是,重新调用方法可能会导致总等待时间超过预期,因为重新调用时是从当前时间开始计算的。
  3. 注意精度问题sleep方法的精度受到线程调度器的影响,因此在实际使用中可能无法完全保证指定的等待时间。特别是在多线程环境下,由于线程之间的竞争和调度的不确定性,实际等待时间可能会比预期的时间稍长或稍短。而wait方法则更多地依赖于其他线程的干预来被唤醒,因此其等待时间也具有一定的不确定性。

五、示例代码

以下是一个简单的示例代码,用于演示waitsleep方法的使用:

public class WaitSleepExample {

    private final Object lock = new Object();
    private boolean condition = false;

    public void waitExample() {
        synchronized (lock) {
            while (!condition) {
                try {
                    System.out.println("Thread is waiting...");
                    lock.wait(); // 当前线程等待,并释放锁
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println("Thread is resumed after waiting.");
        }
    }

    public void notifyExample() {
        synchronized (lock) {
            condition = true;
            lock.notify(); // 唤醒一个等待该锁的线程
        }
    }

    public void sleepExample() {
        try {
            System.out.println("Thread is going to sleep for 2 seconds.");
            Thread.sleep(2000); // 当前线程休眠2秒
            System.out.println("Thread is resumed after sleeping.");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        WaitSleepExample example = new WaitSleepExample();

        // 创建并启动等待线程
        Thread waitThread = new Thread(() -> example.waitExample());
        waitThread.start();

        // 睡眠一段时间以模拟其他操作
        try {
            Thread.sleep(1000); // 主线程休眠1秒以模拟其他操作
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        // 创建并启动通知线程
        Thread notifyThread = new Thread(() -> example.notifyExample());
        notifyThread.start();

        // 创建并启动休眠线程
        Thread sleepThread = new Thread(() -> example.sleepExample());
        sleepThread.start();
    }
}

在这个示例中,我们创建了一个WaitSleepExample类,并定义了三个方法:waitExamplenotifyExamplesleepExamplewaitExample方法使用wait方法让当前线程等待,直到其他线程调用notify方法将其唤醒。notifyExample方法则使用notify方法来唤醒一个等待该锁的线程。sleepExample方法则使用sleep方法让当前线程休眠2秒。

main方法中,我们创建了三个线程:一个等待线程、一个通知线程和一个休眠线程。等待线程首先启动并进入等待状态。然后主线程休眠1秒以模拟其他操作。接着通知线程启动并调用notify方法来唤醒等待线程。最后休眠线程启动并休眠2秒。

六、总结

综上所述,waitsleep方法是Java多线程编程中两个重要的线程控制方法。它们在实现机制、使用场景以及行为表现上存在着显著的差异。sleep方法主要用于模拟延迟操作和控制线程执行节奏,而wait方法则主要用于线程间的通信和解决生产者-消费者问题。在使用这两个方法时,需要注意避免死锁、处理中断异常以及注意精度问题。通过深入理解这两个方法的不同之处,我们可以更好地利用它们来实现高效、可靠的多线程程序。

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

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

相关文章

Vue3 + Vite 项目引入 Typescript

文章目录 一、TypeScript简介二、TypeScript 开发环境搭建三、编译方式1. 自动编译单个文件2. 自动编译整个项目 四、配置文件1. compilerOptions基本选项严格模式相关选项(启用 strict 后自动包含这些)模块与导入相关选项 2. include 和 excludeinclude…

Cyberchef使用功能之-多种压缩/解压缩操作对比

cyberchef的compression操作大类中有大量的压缩和解压缩操作,每种操作的功能和区别是什么,本章将进行讲解,作为我的专栏《Cyberchef 从入门到精通教程》中的一篇,详见这里。 关于文件格式和压缩算法的理论部分在之前的文章《压缩…

Istio分布式链路监控搭建:Jaeger与Zipkin

分布式追踪定义 分布式追踪是一种用来跟踪分布式系统中请求的方法,它可以帮助用户更好地理解、控制和优化分布式系统。分布式追踪中用到了两个概念:TraceID 和 SpanID。 TraceID 是一个全局唯一的 ID,用来标识一个请求的追踪信息。一个请求…

Linux修改/etc/hosts不起作用(ping: xxx: Name or service not known)的解决方法——开启NSCD

​ 问题描述 起因是我在实验室云资源池的一台虚拟机(CentOS 8.5)上的/etc/hosts文件中为Fabric网络节点的域名指定了IP: IP可以ping通,但是ping域名时提示ping: xxx: Name or service not known。 问题本身应该是Linux通用的&a…

Python中Tushare(金融数据库)入门详解

文章目录 Python中Tushare(金融数据库)入门详解一、引言二、安装与注册1、安装Tushare2、注册与获取Token 三、Tushare基本使用1、设置Token2、获取数据2.1、获取股票基础信息2.2、获取交易日历2.3、获取A股日线行情2.4、获取沪股通和深股通成份股2.5、获…

【网络】网络抓包与协议分析

网络抓包与协议分析 一. 以太网帧格式分析 这是以太网数据帧的基本格式,包含目的地址(6 Byte)、源地址(6 Byte)、类型(2 Byte)、数据(46~1500 Byte)、FCS(4 Byte)。 Mac 地址类型 分为单播地址、组播地址、广播地址。 单播地址:是指第一个字节的最低位…

RabbitMQ的工作队列在Spring Boot中实现(详解常⽤的⼯作模式)

上文着重介绍RabbitMQ 七种工作模式介绍RabbitMQ 七种工作模式介绍_rabbitmq 工作模式-CSDN博客 本篇讲解如何在Spring环境下进⾏RabbitMQ的开发.(只演⽰部分常⽤的⼯作模式) 目录 引⼊依赖 一.工作队列模式 二.Publish/Subscribe(发布订阅模式) …

python学习_3.正则表达式

来源:B站/麦叔编程 1. 正则表达式的7个境界 假设有一段文字: text 身高:178,体重:168,学号:123456,密码:9527要确定文本中是否包含数字123456,我们可以用in运算符,也可以使用inde…

Python学习------第十天

数据容器-----元组 定义格式,特点,相关操作 元组一旦定义,就无法修改 元组内只有一个数据,后面必须加逗号 """ #元组 (1,"hello",True) #定义元组 t1 (1,"hello") t2 () t3 tuple() prin…

nodejs基于微信小程序的云校园的设计与实现

摘 要 相比于传统的校园管理方式,智能化的管理方式可以大幅提高校园的管理效率,实现了云校园管理的标准化、制度化、程序化的管理,有效地防止了云校园信息的不规范管理,提高了信息的处理速度和精确度,能够及时、准确地…

Excel——宏教程(精简版)

一、宏的简介 1、什么是宏? Excel宏是一种自动化工具,它允许用户录制一系列操作并将其转换为VBA(Visual Basic for Applications)代码。这样,用户可以在需要时执行这些操作,以自动化Excel任务。 2、宏的优点 我们可以利用宏来…

绿光一字线激光模组:工业制造与科技创新的得力助手

在现代工业制造和科技创新领域,绿光一字线激光模组以其独特的性能和广泛的应用前景,成为了不可或缺的关键设备。这种激光模组能够发射出一条明亮且精确的绿色激光线,具有高精度、高稳定性和长寿命的特点,为各种精密加工和测量需求…

Python Turtle绘图:重现汤姆劈树的经典瞬间

Python Turtle绘图:重现汤姆劈树的经典瞬间 🦀 前言 🦀🐞往期绘画🐞🐋 效果图 🐋🐉 代码 🐉 🦀 前言 🦀 《汤姆与杰瑞》(Tom and Jerr…

Oracle - 多区间按权重取值逻辑 ,分时区-多层级-取配置方案(二)

Oracle - 多区间按权重取值逻辑 ,分时区-多层级-取配置方案https://blog.csdn.net/shijianduan1/article/details/133386281 某业务配置表,按配置的时间区间及组织层级取方案,形成报表展示出所有部门方案的取值; 例如&#xff0…

DataGear 5.2.0 发布,数据可视化分析平台

DataGear 企业版 1.3.0 已发布,欢迎体验! http://datagear.tech/pro/ DataGear 5.2.0 发布,图表插件支持定义依赖库、严重 BUG 修复、功能改进、安全增强,具体更新内容如下: 重构:各模块管理功能访问路径…

详解八大排序(一)------(插入排序,选择排序,冒泡排序,希尔排序)

文章目录 前言1.插入排序(InsertSort)1.1 核心思路1.2 实现代码 2.选择排序(SelectSort)2.1 核心思路2.2 实现代码 3.冒泡排序(BubbleSort)3.1 核心思路3.2 实现代码 4.希尔排序(ShellSort&…

02 —— Webpack 修改入口和出口

概念 | webpack 中文文档 | webpack中文文档 | webpack中文网 修改入口 webpack.config.js (放在项目根目录下) module.exports {//entry设置入口起点的文件路径entry: ./path/to/my/entry/file.js, }; 修改出口 webpack.config.js const path r…

《InsCode AI IDE:编程新时代的引领者》

《InsCode AI IDE:编程新时代的引领者》 一、InsCode AI IDE 的诞生与亮相二、独特功能与优势(一)智能编程体验(二)多语言支持与功能迭代 三、实际应用与案例(一)游戏开发案例(二&am…

ubuntu 16.04 中 VS2019 跨平台开发环境配置

su 是 “switch user” 的缩写,表示从当前用户切换到另一个用户。 sudo 是 “superuser do” 的缩写,意为“以超级用户身份执行”。 apt 是 “Advanced Package Tool” 的缩写,Ubuntu中用于软件包管理的命令行工具。 1、为 root 用户设置密码…

[Docker#11] 容器编排 | .yml | up | 实验: 部署WordPress

目录 1. 什么是 Docker Compose 生活案例 2. 为什么要使用 Docker Compose Docker Compose 的安装 Docker Compose 的功能 使用步骤 核心功能 Docker Compose 使用场景 Docker Compose 文件(docker-compose.yml) 模仿示例 文件基本结构及常见…