JAVA-多线程知识点总结(一)

简介: JAVA-多线程知识点总结(一)

一、相关概念

1.1程序、进程和线程的概念:

程序:是一系列指令的集合,即指的是一段静态的代码,静态对象

进程:是运行的程序,是CPU分配资源的最小单位。

线程:是进程的实体,是CPU调度和分派的基本单位。

1.2进程和线程的主要区别:

1.从属关系不同:进程是正在运行程序的实例,进程中包含了线程,而线程中不能包含进程(即一个进程可以拥有多个线程,而一个线程同时只能被一个进程所有)。


2.描述侧重点不同:进程是操作系统分配资源的基本单位,而线程是操作系统调度的基本单位。


3.共享资源不同:多个进程间不能共享资源,每个进程有自己的堆、栈、虚存空间(页表)、文件描述等信息,而线程可以共享进程资源文件(堆,方法区),并且有自己私有的堆、栈。


4.上下文切换速度不同:线程切换速度较快(指的是从一个线程切换到另一个线程),而进程切换较慢。

5.操纵者不同:一般情况下,进程的操纵者是操作系统,线程的操纵者是编程人员。

1.3引入线程的原因:

1.便于调度。

2.线程可以共享简称的数据和代码,启动和切换速度更快。

3.具有高并发性,可以启动多个线程执行同一个程序的进程。

4.充分利用处理器的功能。

并发:指两个或两个以上的事件在同一时间隔发生,微观上,是把事件分成若干段,使多个进程快速交替的执行。

并行:指两个或两个以上的事件在同一时刻发生,无论是微观还是宏观上,二者都是一起执行的。

1.4多进程和多线程:

多进程:每个进程互相独立,不影响主程序的稳定性,通过增加CPU可以扩充软件的性能,可以减少线程加锁/解锁的影响,极大提高性能。缺点是多进程逻辑控制复杂,需要和主程序交互,需要跨进程边界,进程之间上下文切换比线程之间上下文切换代价大。


多线程:无需跨进程,程序逻辑和控制方式简单,所有线程共享该进程的内存和变量等。缺点是每个线程与主程序共用地址空间,线程之间的同步和加锁控制比较麻烦,一个线程的崩溃会影响到整个进程或者程序的稳定性。

二、创建和启动线程。

2.1线程的创建方式
*****继承Thread类

①创建一个继承于Thread类的子类

②重写Thread类的run()【此线程要执行的操作,声明在此方法体中】

③创建当前Thread的子类的对象

④通过对象调用start():启动当前线程,调用当前线程的run()

class MyThread extends Thread{
 
    //重写run方法,run 表示这个线程需要执行的任务
    @Override
    public void run() {
        System.out.println("这个线程需要执行的任务");
    }
}
 
public class ThreadDemo {
    public static void main(String[] args) {
 
           //创建一个 MyThread 实例
            MyThread myThread = new MyThread();
 
           //start 方法表示这个线程开始执行,注意,这里不是调用 run()方法
          myThread.start();
 
            }
         }
*****实现Runnable接口

①创建一个实现Runnable接口的类

②实现接口中的run()【此线程要执行的操作,声明在此方法体中】

③创建当前实现类的对象

④将此对象作为参数传递到Thread类的构造器中,创建Thread类的实例

⑤Thread类的实例调用start():

 
class MyRunnable implements Runnable{
 
    //需要重写run方法
    @Override
    public void run() {
        System.out.println("这个线程需要执行的任务");
    }
}
 
public class ThreadDemo {
    public static void main(String[] args) {
 
         
           //创建 Thread 类实例, 调用 Thread 的构造方法时将 Runnable 对象作为参数。
           Thread thread = new Thread(new MyRunnable());
 
           //start 方法表示这个线程开始执行,注意,这里不是调用 run()方法
          myThread.start();
 
            }
         }

*****实现Callable(jdk5.0增)

实现者定义了一个不带参数的方法,称为call。 Callable接口与Runnable接口类似,两者都是为其实例可能由另一个线程执行的类设计的。


与Runnable方式对比的好处是:


---call()可以有返回值,更加灵活。

---call()可以使用throws的方式处理异常。

---callable使用了泛型参数,可以指明具体的call()返回值类型。

缺点:如果在主线程中需要获取分线程call()的返回值,则此时的主线程是阻塞状态的。

 
 
public class MyCallable implements Callable<Integer> {
    public Integer call() throws Exception {
        int sum = 0;
        for (int i = 1; i <= 100; i++) {
            sum += i;
        }
        return sum;
    }
 
    public static void main(String[] args) throws InterruptedException和 ExecutionException {
        MyCallable myCallable = new MyCallable();
        FutureTask<Integer> futureTask = new FutureTask<Integer>(myCallable);
        Thread thread = new Thread(futureTask);
        thread.start();
        try {
            int result = futureTask.get();
            System.out.println("The result is " + result);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }
}

*****使用线程池

线程池解决两个不同的问题:它们通常在执行大量异步任务时提高性能,因为减少了每个任务的调用开销,并且它们提供了一种方法来限制和管理执行任务集合时消耗的资源(包括线程)。每个ThreadPoolExecutor(阿里推荐)还维护一些基本的统计信息,比如完成任务的数量。


使用线程池的好处:


---提高了程序执行的效率。(线程早已提前创建好了)


---提高了资源的复用率。(执行完的线程并未销毁,而是可以继续执行其他的任务)


---可以设置相关的参数,对线程池中的线程的使用进行管理。

 java.util.concurrent.ThreadPoolExecutor类的构造器(其一):
 
public ThreadPoolExecutor(int corePoolSize,
                         int maximumPoolSize,
             long keepAliveTime,
             TimeUnit unit,
             BlockingQueue<Runnable> workQueue,
             ThreadFactory threadFactory,
                         RejectedExecutionHandler handler) 
     {
      if (corePoolSize < 0 ||
      maximumPoolSize <= 0 ||
      maximumPoolSize < corePoolSize ||
      keepAliveTime < 0)
      throw new IllegalArgumentException();
      if (workQueue == null || threadFactory == null || handler == null)
      throw new NullPointerException();
      this.acc = System.getSecurityManager() == null ?null :
      AccessController.getContext();
      this.corePoolSize = corePoolSize;
      this.maximumPoolSize = maximumPoolSize;
      this.workQueue = workQueue;
      this.keepAliveTime = unit.toNanos(keepAliveTime);
      this.threadFactory = threadFactory;
      this.handler = handler;
}
相关文章
|
3天前
|
安全 Java API
java如何请求接口然后终止某个线程
通过本文的介绍,您应该能够理解如何在Java中请求接口并根据返回结果终止某个线程。合理使用标志位或 `interrupt`方法可以确保线程的安全终止,而处理好网络请求中的各种异常情况,可以提高程序的稳定性和可靠性。
28 6
|
16天前
|
存储 监控 小程序
Java中的线程池优化实践####
本文深入探讨了Java中线程池的工作原理,分析了常见的线程池类型及其适用场景,并通过实际案例展示了如何根据应用需求进行线程池的优化配置。文章首先介绍了线程池的基本概念和核心参数,随后详细阐述了几种常见的线程池实现(如FixedThreadPool、CachedThreadPool、ScheduledThreadPool等)的特点及使用场景。接着,通过一个电商系统订单处理的实际案例,分析了线程池参数设置不当导致的性能问题,并提出了相应的优化策略。最终,总结了线程池优化的最佳实践,旨在帮助开发者更好地利用Java线程池提升应用性能和稳定性。 ####
|
12天前
|
安全 算法 Java
Java多线程编程中的陷阱与最佳实践####
本文探讨了Java多线程编程中常见的陷阱,并介绍了如何通过最佳实践来避免这些问题。我们将从基础概念入手,逐步深入到具体的代码示例,帮助开发者更好地理解和应用多线程技术。无论是初学者还是有经验的开发者,都能从中获得有价值的见解和建议。 ####
|
12天前
|
Java 调度
Java中的多线程编程与并发控制
本文深入探讨了Java编程语言中多线程编程的基础知识和并发控制机制。文章首先介绍了多线程的基本概念,包括线程的定义、生命周期以及在Java中创建和管理线程的方法。接着,详细讲解了Java提供的同步机制,如synchronized关键字、wait()和notify()方法等,以及如何通过这些机制实现线程间的协调与通信。最后,本文还讨论了一些常见的并发问题,例如死锁、竞态条件等,并提供了相应的解决策略。
34 3
|
13天前
|
监控 Java 开发者
深入理解Java中的线程池实现原理及其性能优化####
本文旨在揭示Java中线程池的核心工作机制,通过剖析其背后的设计思想与实现细节,为读者提供一份详尽的线程池性能优化指南。不同于传统的技术教程,本文将采用一种互动式探索的方式,带领大家从理论到实践,逐步揭开线程池高效管理线程资源的奥秘。无论你是Java并发编程的初学者,还是寻求性能调优技巧的资深开发者,都能在本文中找到有价值的内容。 ####
|
16天前
|
监控 Java 数据库连接
Java线程管理:守护线程与用户线程的区分与应用
在Java多线程编程中,线程可以分为守护线程(Daemon Thread)和用户线程(User Thread)。这两种线程在行为和用途上有着明显的区别,了解它们的差异对于编写高效、稳定的并发程序至关重要。
26 2
|
16天前
|
监控 Java 开发者
Java线程管理:守护线程与本地线程的深入剖析
在Java编程语言中,线程是程序执行的最小单元,它们可以并行执行以提高程序的效率和响应性。Java提供了两种特殊的线程类型:守护线程和本地线程。本文将深入探讨这两种线程的区别,并探讨它们在实际开发中的应用。
23 1
|
18天前
|
安全 Java 开发者
Java中的多线程编程:从基础到实践
本文深入探讨了Java多线程编程的核心概念和实践技巧,旨在帮助读者理解多线程的工作原理,掌握线程的创建、管理和同步机制。通过具体示例和最佳实践,本文展示了如何在Java应用中有效地利用多线程技术,提高程序性能和响应速度。
52 1
|
2月前
|
存储 消息中间件 资源调度
C++ 多线程之初识多线程
这篇文章介绍了C++多线程的基本概念,包括进程和线程的定义、并发的实现方式,以及如何在C++中创建和管理线程,包括使用`std::thread`库、线程的join和detach方法,并通过示例代码展示了如何创建和使用多线程。
56 1
C++ 多线程之初识多线程
|
2月前
|
Java 开发者
在Java多线程编程中,创建线程的方法有两种:继承Thread类和实现Runnable接口
【10月更文挑战第20天】在Java多线程编程中,创建线程的方法有两种:继承Thread类和实现Runnable接口。本文揭示了这两种方式的微妙差异和潜在陷阱,帮助你更好地理解和选择适合项目需求的线程创建方式。
26 3