首页 > 其他分享 >多线程基本常识

多线程基本常识

时间:2024-05-27 23:33:53浏览次数:22  
标签:调用 等待 lock 线程 基本常识 多线程 方法 wait

多线程的状态

    在Java中,一个线程的生命周期有以下几种状态:

  1. 新建(New):当线程对象被创建时,线程处于新建状态。此时线程对象存在,但还没有调用start()方法启动线程。

  2. 运行(Runnable):当线程调用start()方法后,线程进入就绪状态,等待被分配CPU时间片执行。当线程获取到CPU时间片后,线程进入运行状态执行任务。

  3. 阻塞(Blocked):线程在执行过程中,可能会因为某些原因(如等待I/O操作、等待获取锁等)而暂时停止执行。此时线程进入阻塞状态,等待特定条件满足后重新进入就绪状态。

  4. 等待(Waiting):线程在执行过程中,可能会因为调用了wait()方法而进入等待状态。此时线程释放持有的锁,并等待其他线程调用notify()、notifyAll()方法唤醒自己。

  5. 超时等待(Timed Waiting):线程在执行过程中,可能会因为调用了sleep()方法或者带有超时参数的wait()方法而进入超时等待状态。超过指定时间后,线程会被自动唤醒并进入就绪状态。

  6. 终止(Terminated):线程执行完任务或者发生异常导致线程终止时,线程进入终止状态。

线程的状态之间的流转如下:

  1. 新建 -> 运行:调用start()方法启动线程,线程进入就绪状态等待CPU调度。

  2. 运行 -> 阻塞:线程在执行过程中,由于某些原因(如等待I/O操作、等待获取锁等)暂停执行。

  3. 阻塞 -> 运行:阻塞状态解除后,线程重新进入就绪状态等待CPU调度。

  4. 运行 -> 等待:线程调用了wait()方法,线程进入等待状态。

  5. 等待 -> 运行:其他线程调用了notify()、notifyAll()方法,或者等待时间到达,线程被唤醒并进入就绪状态。

  6. 运行 -> 超时等待:线程调用了sleep()方法或者带有超时参数的wait()方法,线程进入超时等待状态。

  7. 超时等待 -> 运行:超时等待时间到达,线程被自动唤醒并进入就绪状态。

  8. 运行 -> 终止:线程执行完任务或者发生异常导致线程终止。

启动线程方法 start()和 run()区别

     start()和run()是Java中用于启动线程的两种方法。

start()方法用于启动一个新的线程,并在新的线程中执行run()方法。当start()方法被调用时,会创建一个新的线程,并且该线程会执行run()方法中的代码。

run()方法定义了线程的主体,包含了线程要执行的代码。当run()方法被调用时,会在当前线程中执行run()方法中的代码,而不会创建新的线程。

所以,区别在于start()方法会创建一个新的线程,而run()方法只是在当前线程中执行run()方法中的代码。一般情况下,应该使用start()方法来启动线程,这样可以实现多线程并发执行。使用run()方法启动线程,相当于在当前线程中顺序执行run()方法中的代码,不会实现多线程的效果。

线程中的 wait()和 sleep()方法区别

    

wait()方法和sleep()方法都是线程中的方法,但是它们的功能和使用方式有所不同。

  1. wait()方法:
  • wait()方法是Object类中的方法,需要在同步代码块或同步方法中使用。当一个线程调用对象的wait()方法时,该线程会释放对象的锁,并进入等待状态,直到其他线程调用同一个对象的notify()或notifyAll()方法来唤醒等待中的线程。
  • wait()方法的调用可以帮助线程间的协调合作,允许线程之间等待某个条件满足后再继续执行。
  • wait()方法必须在synchronized块中调用,否则会在运行时抛出IllegalMonitorStateException异常。
  1. sleep()方法:
  • sleep()方法是Thread类的静态方法,用于暂停当前线程的执行一段时间,不释放当前线程所持有的锁。
  • sleep()方法的调用不需要在同步代码块或同步方法中,任何地方都可以调用。
  • sleep()方法可以用来模拟线程间的时间间隔,或者在某些需要睡眠一段时间的情况下使用。

多线程同步方法

  1. synchronized关键字:通过在方法或代码块前加上synchronized关键字,可以实现对方法或代码块的同步。一次只能有一个线程访问该同步方法或代码块,其他线程需要等待。 代码示例:
class Counter {
    private int count;

    public synchronized void increment() {
        count++;
    }
}
  1. Lock接口:Java提供了Lock接口及其实现类ReentrantLock来实现更灵活的同步操作。通过调用lock()方法获得锁,调用unlock()方法释放锁。 代码示例:
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

class Counter {
    private int count;
    private Lock lock;

    public Counter() {
        count = 0;
        lock = new ReentrantLock();
    }

    public void increment() {
        lock.lock();
        try {
            count++;
        } finally {
            lock.unlock();
        }
    }
}

  1. synchronized关键字与wait()、notify()、notifyAll()方法:可以使用synchronized关键字结合wait()、notify()、notifyAll()方法实现线程间的等待和唤醒操作。 代码示例:
class MyThread implements Runnable {
    private Object lock;

    public MyThread(Object lock) {
        this.lock = lock;
    }

    @Override
    public void run() {
        synchronized (lock) {
            try {
                // 线程等待
                lock.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            // 线程被唤醒后执行的操作
        }
    }
}

public class Main {
    public static void main(String[] args) throws InterruptedException {
        Object lock = new Object();
        Thread thread = new Thread(new MyThread(lock));
        thread.start();
        
        // 唤醒线程
        synchronized (lock) {
            lock.notify();
        }
    }
}

总结

   

多线程的状态可以总结为以下几种:

  1. 新建(New):线程被创建但还没有启动。

  2. 就绪(Runnable):线程被调度,并且准备开始执行,但还没有开始执行。

  3. 运行(Running):线程正在执行中。

  4. 阻塞(Blocked):线程因为某种原因被阻塞,例如等待 IO 操作完成或在等待锁释放。

  5. 等待(Waiting):线程被指定等待某个条件满足,例如调用了对象的 wait() 方法。

  6. 超时等待(Timed Waiting):线程被指定等待一段时间,例如调用了 Thread.sleep() 方法或带有超时参数的 wait() 方法。

  7. 终止(Terminated):线程执行完毕或者异常终止。

    

标签:调用,等待,lock,线程,基本常识,多线程,方法,wait
From: https://blog.csdn.net/Flying_Fish_roe/article/details/139250345

相关文章

  • 详解PySide多线程【Python-Pyside图形界面绘制#2】
    在了解pyside多线程之前,如果是初学者可以先去看看我的第一篇文章《超详细实例详解Python多线程》,文中有对多线程的概念进行详细介绍,如果有相关基础可直接跳过。【Python】超详细实例讲解python多线程(threading模块)_pythonthreading介绍-CSDN博客https://blog.csdn.net/Xiao_......
  • Java面试--多线程
    目录Java多线程1.什么是线程?什么是多线程?2.多线程的生命周期?3.线程常出现的基本方法?4.wait()和sleep()的区别?5.实现多线程的方式?6.start()和run()的区别?7.如何正确停止线程?8.使用线程池的好处?9.线程池主要参数?10.线程池的执行过程?11.四大拒绝策略?12.线程池的各个状态?13.......
  • 进程间通信(管道)、多线程理论、开设多线程的两种方式、threading介绍、线程之间共享数
    【一】进程间通信(管道)借助于消息队列,进程可以将消息放入队列中,然后由另一个进程从队列中取出。这种通信方式是非阻塞的,即发送进程不需要等待接收进程的响应即可继续执行。multiprocessing模块支持两种形式:队列和管道,这两种方式都是使用消息传递的进程间通信(IPC)有两种方式:队列......
  • 【Python并发编程指南】多线程、多进程与异步编程比较与选择
    ......
  • 第一部分 多线程基础
    本系列博客,主要是面向Java8的源码。本系列博客主要参考汪文君老师《Java高并发编程详解》一书转载请注明出处,多谢~。1.线程的start方法剖析/***Causesthisthreadtobeginexecution;theJavaVirtualMachine*callsthe<code>run</code>methodofthisth......
  • Java 多线程编程 力扣实题
    多线程编程实例了解内存模型、线程通信和线程安全之后,对多线程编程已经有了理论上的认知,现在来实战一下。所有题目在https://leetcode.cn/problemset/concurrency/。按序打印题干描述给你一个类:publicclassFoo{publicvoidfirst(){print("first");}publicvoidseco......
  • Java 多线程编程基础
    我们的应用程序都是运行在多线程的环境下的,在多线程环境下的许多问题我们都了解吗?线程间如何进行数据交换?线程间如何进行通信与协作?共享一个资源时如何保证线程安全?线程数据交换线程之间无法直接访问对方工作内存中的变量,必须通过主内存进行变量的传递。例如,线程A、B共享一......
  • python多线程
    1、当程序中有耗时操作时,我们应该使用多线程来进行操作。多线程就像是多辆火车,可以在不同的轨道上同时运行。而进程就像是火车站,正在运行的一个程序的实例。python中多线程可以提供threading模块来实现。简单的多线程案例:importthreadingimporttime#定义线程执行的......
  • 多线程抢沙包游戏
    幼儿园玩抢沙包游戏,共计100个沙包,有10个小朋友(4男6女),男生每次拿3个沙包,女生每次拿2个沙包,如果剩余的沙包不够每次拿的数量,则游戏停止,请用java多线程模拟上述游戏过程。importjava.util.ArrayList;importjava.util.List;importjava.util.concurrent.CountDownLatch;import......
  • 深入解析Python并发的多线程和异步编程
    在Python编程中,多线程是一种常用的并发编程方式,它可以有效地提高程序的执行效率,特别是在处理I/O密集型任务时。Python提供了threading模块,使得多线程编程变得相对简单。本文将深入探讨threading模块的基础知识,并通过实例演示多线程的应用。1.多线程基础概念在开始之前,让我们......