java技术文档--多线程(2)--线程基础

什么是线程和进程的概念

线程:

        线程是计算机中执行的最小单位,也是操作系统进行调度和分配资源的基本单位之一。一个进程可以包含多个线程,每个线程都有自己的执行路径和独立的栈空间,但是它们共享相同的内存空间和其他资源。

        线程之间可以并行地执行,每个线程可以独立地完成特定的任务。通过使用多线程,可以实现并发执行多个任务,提高了程序的效率和资源利用率。同时,线程之间可以通过共享内存来进行通信,以便协调彼此的工作。

        线程可以分为用户线程和内核线程。用户线程是由应用程序创建和管理的,操作系统对其无感知;而内核线程是由操作系统内核创建和管理的,操作系统可以直接对其进行调度。用户线程的切换开销较小,但受到单个进程的限制,而内核线程可以充分利用多核处理器,并具有更好的可靠性和稳定性。

        需要注意的是,线程间的并发执行可能会引发一些问题,如竞态条件、死锁和资源争用等。因此,在编写多线程程序时,需要进行适当的同步和互斥措施来保证线程之间的安全与正确性。

进程:

        进程是计算机中正在运行的程序的实例。它是操作系统进行资源分配和调度的基本单位。每个进程都有自己的地址空间、代码、数据和文件等资源。

        一个进程可以包含多个线程,线程是在进程内部执行的独立执行路径。线程共享进程的内存空间和其他资源,但拥有自己的栈空间和执行上下文。

        进程之间是相互独立的,彼此之间不能直接访问对方的内存和状态。进程通过操作系统提供的机制进行通信,如管道、共享内存、消息队列等。

        每个进程都有自己的状态,包括就绪、运行、阻塞等。操作系统根据调度算法来决定哪些进程可以运行,并为其分配CPU时间片和其他资源。进程的调度和切换会导致一些开销,因此优化进程的并发性能是很重要的。

        进程具有独立性、稳定性和安全性,在多任务操作系统中,多个进程可以并行执行,提高了系统的效率和资源利用率。同时,进程之间的隔离性也使得一个进程的错误不会影响到其他进程的正常运行。

线程和进程之间的关系

一个进程中包含很多线程,进程和线程存在包含关系。

创建线程的方式(继承Thread类、实现Runnable接口、使用线程池等)

继承Thread类:通过继承Thread类并重写其run()方法来创建新的线程。然后可以创建线程对象,并通过调用start()方法来启动线程

class MyThread extends Thread {
    public void run() {
        // 线程执行的代码
    }
}

// 创建线程对象并启动线程
MyThread thread = new MyThread();
thread.start();

 实现Runnable接口:定义一个类实现Runnable接口,并实现其run()方法。然后创建Thread对象,将该Runnable对象作为参数传递给Thread构造函数,并调用start()方法来启动线程

class MyRunnable implements Runnable {
    public void run() {
        // 线程执行的代码
    }
}

// 创建Runnable对象
MyRunnable runnable = new MyRunnable();

// 创建线程对象并启动线程
Thread thread = new Thread(runnable);
thread.start();

 使用Callable和Future:通过实现Callable接口并实现其call()方法,可以创建具有返回值的线程任务。然后使用ExecutorService提交Callable任务并获取Future对象,通过Future对象可以获取任务执行结果。

import java.util.concurrent.*;

class MyCallable implements Callable<String> {
    public String call() throws Exception {
        // 线程执行的代码
        return "Hello, World!";
    }
}

// 创建ExecutorService线程池
ExecutorService executor = Executors.newFixedThreadPool(1);

// 提交Callable任务并获取Future对象
Future<String> future = executor.submit(new MyCallable());

// 获取任务执行结果
String result = future.get();

// 关闭线程池
executor.shutdown();

 使用线程池:通过使用线程池,可以重复利用线程对象,避免频繁创建和销毁线程的开销。可以使用Executor框架提供的ThreadPoolExecutor类或Executors工具类来创建线程池。

import java.util.concurrent.*;

// 创建固定大小的线程池
ExecutorService executor = Executors.newFixedThreadPool(5);

// 提交Runnable任务
executor.execute(new Runnable() {
    public void run() {
        // 线程执行的代码
    }
});

// 提交Callable任务并获取Future对象
Future<String> future = executor.submit(new Callable<String>() {
    public String call() throws Exception {
        // 线程执行的代码
        return "Hello, World!";
    }
});

// 关闭线程池
executor.shutdown();

总结: 

这些创建线程的方式有以下区别和使用场景:

  1. 继承Thread类:通过继承Thread类创建线程,可以直接重写run()方法来定义线程要执行的逻辑。这种方式简单直接,适合对于线程的控制较少的情况。但由于Java是单继承的,因此如果已经继承了其他类,则无法再使用该方式创建线程。

  2. 实现Runnable接口:通过实现Runnable接口创建线程,将线程任务的定义与线程对象分离开来。这种方式可以更好地实现代码的复用性,一个Runnable对象可以被多个线程共享。同时,由于可以实现多个接口,所以比继承Thread类的方式更灵活。

  3. 使用Callable和Future:通过实现Callable接口创建具有返回值的线程任务,并通过Future对象获取任务的执行结果。这种方式允许在任务执行完成后获取结果,并且可以捕获任务执行过程中抛出的异常。适合需要获取任务执行结果的场景,但需要注意的是,Callable任务必须通过ExecutorService提交才能执行。

  4. 使用线程池:通过使用线程池,可以重复利用线程对象,避免频繁创建和销毁线程的开销。线程池会管理线程的生命周期、调度任务并提供更好的资源管理和线程控制的能力。适合需要处理大量短期任务的场景,可以控制线程数目、设置任务队列和管理线程池的生命周期。

根据具体的需求,在选择创建线程的方式时可以考虑以下几个因素:

  • 线程控制:如果对线程的控制较少,只需要简单地启动线程并执行特定的逻辑,可以使用继承Thread类或实现Runnable接口。
  • 返回结果:如果需要获取任务的执行结果,可以使用Callable和Future来创建具有返回值的线程任务。
  • 资源利用:如果需要管理和控制线程的生命周期,并提供更高效的资源利用,可以使用线程池。

需要根据具体的应用场景和需求进行选择,合理地使用各种创建线程的方式可以提高程序的性能和可维护性。

线程的生命周期(新建、就绪、运行、阻塞、死亡)

一个线程的生命周期可以分为以下几个阶段:

  1. 新建状态(New):当通过创建Thread对象或者通过线程池获取新的线程时,线程处于新建状态。此时线程已经被创建,但还没有开始执行。

  2. 就绪状态(Runnable):当线程调用start()方法后,线程进入就绪状态。在就绪状态中,线程已经准备好运行,等待CPU进行调度。

  3. 运行状态(Running):一旦得到CPU时间片,线程进入运行状态。此时线程开始执行run()方法中的代码。

  4. 阻塞状态(Blocked):在线程执行过程中,如果遇到某些条件阻塞了线程的执行,线程将进入阻塞状态。常见的例子包括等待I/O操作、等待获取锁、等待其他线程完成等。

  5. 等待状态(Waiting):线程进入等待状态表示线程暂时停止执行,直到某个特定条件满足,例如调用了wait()方法、join()方法或者LockSupport的park()方法。

  6. 超时等待状态(Timed Waiting):和等待状态类似,但是可以设置等待的时间,超过指定的时间后线程会重新进入就绪状态。例如调用了sleep()方法、wait()方法的带有超时参数的重载方法、join()方法的带有超时参数

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值