java-多线程【初识】

1.什么是线程? 什么是进程? 线程和进程是什么关系?

线程:线程(Thread)是操作系统能够进行调度和执行的最小单位,也是程序执行的路径。简单来说,线程是进程中的一个独立执行单元,可以并发执行多个任务。

单线程(Single-Threaded):单线程指的是在一个进程内只有一个执行路径,即同一时间只能执行一个任务。程序按照顺序逐行执行,一次只能处理一个请求或任务。在单线程模式下,如果某个任务阻塞了或耗时较长,会导致整个程序的执行被阻塞,直到该任务完成。  

多线程(Multi-Threaded):多线程指在一个进程内有多个执行路径,并且这些执行路径可以并发执行多个任务。每个线程独立地执行自己的任务,不受其他线程的影响。多线程模式可以提高程序的响应性和效率,特别是对于耗时的操作。多线程可以同时执行多个任务,可以将计算密集型任务和I/O操作分开处理,从而充分利用处理器和其他资源。

进程:进程(Process)是计算机科学中的重要概念,它代表着一个正在执行的程序实例。每个进程都有独立的内存空间、资源和系统标识符,它们是操作系统进行任务调度和资源管理的基本单位。

1. 内存空间:每个进程都有自己独立的虚拟地址空间,用于存储程序代码、数据、堆栈等。进程的地址空间是相对独立的,使得进程之间的内存空间互不干扰。

2. 资源:进程可以使用和管理计算机系统的资源,包括处理器、内存、文件、I/O设备等。每个进程都拥有自己的打开文件表、网络连接、权限等资源。

3. 系统标识符:每个进程都有一个唯一的进程标识符(PID),用于操作系统识别和管理进程。PID可以用来查找和控制进程,进行进程间通信和资源共享。

4. 进程控制块(PCB):操作系统为每个进程分配一个数据结构,称为进程控制块。PCB包含了进程的相关信息,如进程状态(运行、就绪、阻塞)、程序计数器、寄存器内容、打开文件表、用户和组ID等。

5. 进程间通信(IPC):不同的进程之间可以通过进程间通信机制进行数据交换和共享。常见的IPC机制包括管道、消息队列、信号量、共享内存等。

6. 进程调度:操作系统使用调度算法来决定哪个进程可以执行,并分配处理器时间片给进程进行执行。调度算法的目标是提高系统的响应性、资源利用率和公平性。

7. 进程状态:进程可以处于不同的状态,如运行状态(Running)、就绪状态(Ready)、阻塞状态(Blocked)等。进程状态的转换是由操作系统进行管理和调度。

进程提供了一种隔离和独立运行的环境,使得不同的程序可以同时运行,并保护了进程之间的数据和资源。每个进程拥有自己的地址空间和资源,可以并发执行任务。进程间可以进行通信和共享数据,但需要通过进程间通信的机制来实现。

线程和进程是操作系统中的两个非常重要的概念,它们之间存在着紧密的关系。

  • 一个进程至少有一个线程,即主线程。主线程主要用于执行程序的入口点,创建其他线程,并协调不同线程之间的工作。
  • 同一进程内的多个线程共享相同的虚拟地址空间、文件描述符等资源。这意味着线程之间可以直接读写共享的变量,通过共享内存进行通信,而无需进行复杂的进程间通信。
  • 不同进程之间的线程是相互独立的,线程之间无法直接共享变量和资源。如果需要在不同进程之间共享数据,需要使用进程间通信的机制,如管道、消息队列、共享内存等。
  • 进程和线程之间共享某些资源,如文件描述符、信号处理器等。这意味着一个线程对某个共享资源的修改会影响到其他线程或进程对该资源的访问。

总而言之,线程是进程的一部分,是进程内的执行路径,线程共享进程的内存空间和资源。通过多线程编程,可以实现并发和并行的任务执行,提高程序的响应性和效率。而进程提供了一种隔离和独立运行的环境,为线程提供了运行的基础。

2.java中多线程的创建

通过继承Thread类:

  • 定义一个继承自Thread类的子类,并重写其run()方法,该方法定义了线程的执行逻辑。
  • 在子类中可以添加其他成员变量和方法,用于辅助线程的执行。
  • 创建子类的实例,并调用start()方法来启动线程。
// 定义一个类,继承Thread类,重写run()方法作为线程的执行体
public class MyThread extends Thread {
    public void run() {
        // 线程任务逻辑
        System.out.println("Thread is running...");
    }
}

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

它的优缺点:
优点:

1 .简单直观:相对于实现Runnable接口的方式,继承Thread类的方式代码比较简单,逻辑也比较直观,适合于简单的多线程场景。
 
2 .类继承关系清晰:继承Thread类创建的线程类是Thread类的子类,清晰地表示了线程与线程类之间的关系。

3 .方便访问Thread类的方法:通过继承Thread类,可以直接访问Thread类提供的一些方法,如sleep()、yield()、join()等。

缺点:

1.无法继承其他类:Java中的类是单继承的,通过继承Thread类创建的线程类已经继承了Thread类,如果需要继承其他类,则无法实现多继承。

2.代码复用性差:继承Thread类的方式无法充分利用类的复用性,因为每次创建线程都需要创建一个新的线程类对象,无法共享同一个线程类实例。

3.无法满足共享资源的需求:由于无法共享同一个线程类实例,如果需要多个线程共享某个资源,就会显得比较困难。

4.阻止其他方法重写:继承Thread类会将Thread类中的方法暴露出来,如果不希望某些方法被重写,就需要在子类中进行限制。

通过实现Runnable接口:

  • 定义一个类实现Runnable接口,并实现其中的run()方法,该方法定义了线程的执行逻辑。
  • 创建该类的实例,并将其作为参数传递给Thread类的构造函数。
  • 调用Thread对象的start()方法来启动线程。
// 定义一个类,实现Runnable接口,实现run()方法作为线程的执行体
public class MyRunnable implements Runnable {
    public void run() {
        // 线程任务逻辑
        System.out.println("Thread is running...");
    }
}

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

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

它的优缺点:
优点:

1.支持多继承:Java中的类是单继承的,但是通过实现Runnable接口,可以避免继承Thread类时的单继承限制,同时还可以继续继承其他类,增加了代码的灵活性和扩展性。

2.代码的解耦:实现Runnable接口将线程的执行逻辑与线程类本身解耦,使得代码的结构更加清晰和可维护。线程类只需要关注线程的行为,而具体的执行逻辑可以放在实现Runnable接口的类中实现。

3.资源共享:多个线程可以共享同一个实现Runnable接口的对象,这使得多个线程之间可以更方便地进行数据共享和通信,提高了编程的灵活性。

4.适用于任务资源的拆分和组合:实现Runnable接口的方式更适合于分解和组合任务。可以将一个复杂的任务拆分成多个Runnable任务,然后利用多个线程同时执行这些Runnable任务,从而提高程序的并发性能。

缺点:

1.无法直接访问Thread类的方法和属性:相对于继承Thread类,实现Runnable接口无法直接访问Thread类的一些方法和属性,如sleep()、yield()、join()等方法,如果需要使用这些方法,则需要通过Thread.currentThread()来获取当前线程的引用。

2.需要创建Thread对象:实现Runnable接口的类需要通过创建Thread对象,并将其作为参数传递给Thread类的构造方法来创建线程。这需要额外的代码和对象创建开销。

两种方式都可以用来创建多线程,但相比较而言,使用Runnable接口的方式更为灵活。它可以避免Java的单继承限制,并且可以将Runnable对象传递给多个线程去共享执行体。在实际开发中,推荐使用Runnable接口创建多线程。

另外,还可以使用匿名内部类的方式直接创建Thread对象或Runnable对象。这种方式可以简化代码,尤其是对于一些简单的线程逻辑。

// 使用匿名内部类创建Thread对象
Thread myThread = new Thread() {
    public void run() {
        // 线程任务逻辑
        System.out.println("Thread is running...");
    }
};
myThread.start();

// 使用匿名内部类创建Runnable对象
Runnable myRunnable = new Runnable() {
    public void run() {
        // 线程任务逻辑
        System.out.println("Thread is running...");
    }
};

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

在多线程模式下,线程之间共享进程的资源和内存空间,它们可以访问相同的变量和数据,从而实现数据共享和通信。但也需要注意线程安全的问题,多个线程同时访问和修改共享数据时可能会导致数据不一致的问题,需要采取相应的同步机制来保证线程的安全性。

多线程编程需要注意以下几点:

  • 线程同步:使用同步机制(如锁、信号量、条件变量)来防止多个线程对共享数据的并发访问导致的问题,例如数据竞争和死锁。
  • 线程通信:线程之间可能需要进行协作和通信,通过使用线程间的通信机制(如信号量、条件变量、管道、队列)来传递消息和共享数据。
  • 死锁:需要注意多线程编程中的死锁问题,即多个线程相互等待对方释放资源而导致无法继续执行的情况。需要小心设计线程之间的资源请求和释放顺序,以避免死锁的发生。

单线程模式适合简单的顺序执行任务,而多线程模式适合处理并发执行的任务,并可以利用多核处理器和其他多线程优化技术提高程序的性能和响应性。但多线程编程也要注意线程同步和线程安全的问题,确保多个线程能够正确地访问共享数据和资源。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值