栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

线程,线程池总结

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

线程,线程池总结

线程:

多核:多个cpu 一个cpu一个时间节点只能处理一个线程

程序:软件,工程

进程:正在运行的程序(至少有一个线程)

线程:进程中的任务单位

并发:指两个或多个事件在同⼀个时间段内发⽣。

并⾏:指两个或多个事件在同⼀时刻发⽣(同时发⽣)。

主方法就是一个线程       主线程 main 在 main() 调⽤时候被创建

创建线程的方法

方式一: 只能继承一个类, 功能性单一
  1.自定义类, 继承Thread
  2.重写run方法
  3.在主程序中创建线程对象
  4.开启线程 start()

Thread的构造:

public Thread() :分配⼀个新的线程对象。

public Thread(String name) :分配⼀个指定名字的新的线程对象。

public Thread(Runnable target) :分配⼀个带有指定⽬标新的线程对象。

public Thread(Runnable target, String name) :分配⼀个带有指定⽬标新的线程对象并指定名字。
方式二: 实现接口
  1.自定义类, 实现Runnable接口
  2.实现run方法
  3.创建线程对象    使用Runnable对象来构造
  4.开启线程 start


方式三: 匿名内部类

Thread 和 Runnable 的区别

如果⼀个类继承 Thread,则不适合资源共享。但是如果实现了 Runable 接⼝的话,则很容易的实现资源共享。

总结:实现 Runnable 接⼝⽐继承 Thread 类所具有的优势:

1. 适合多个相同的程序代码的线程去共享同⼀个资源。

2. 可以避免 java 中的单继承的局限性。

3. 增加程序的健壮性,实现解耦操作,代码可以被多个线程共享,代码和线程独⽴。

4. 线程池只能放⼊实现 Runable 或 Callable 类线程,不能直接放⼊继承 Thread 的类。

Run方法任何时刻都有可能被打断

优先级只是提升了这个线程的执行概率

GC -> 垃圾回收机制

setDaemon(true):如果 true ,将此线程标记为守护线程。设置守护线程,所有的”前置”线程都结束了,守护线程也结束(当运行的唯一线程都是守护进程线程时,Java虚拟机将退出。)

线程通信  sleep()等待 带着锁 wait()等待会释放锁(别的等待会释放锁)

join(long millis)等待最多millis毫秒(系统过去millis毫秒)后无论之前线程有没有结束,都开始

线程同步:

1. 同步代码块:synchronized 关键字可以⽤于⽅法中的某个区块中,表示只对这个区块的资源实⾏互斥访问

2. 同步⽅法:使⽤ synchronized 修饰的⽅法,就叫做同步⽅法,保证A线程执⾏该⽅法的时候,其他线程只能在⽅法外等着。

3. 锁机制:java.util.concurrent.locks.Lock 机制提供了⽐synchronized代码块和synchronized⽅法更⼴泛的锁定操作,同步代码块/同步⽅法具有的功能Lock都有,除此之外更强⼤,更体现⾯向对象。

Lock锁也称同步锁,加锁与释放锁⽅法化了,如下:

public void lock() :加同步锁。 public void unlock() :释放同步锁。

线程通信: 等待唤醒机制   wait/notify 就是线程间的⼀种协作机制。

调⽤wait和notify⽅法需要注意的细节:

1. wait⽅法与notify⽅法必须要由同⼀个锁对象调⽤。因为:对应的锁对象可以通过notify唤醒使⽤同⼀个锁对象调⽤的wait⽅法后的线程。

2. wait⽅法与notify⽅法是属于Object类的⽅法的。因为:锁对象可以是任意对象,⽽任意对象的所属类都是继承了Object类的。

3. wait⽅法与notify⽅法必须要在同步代码块或者是同步函数中使⽤。因为:必须要通过锁对象调⽤这2个⽅法。

等待唤醒机制其实就是经典的“⽣产者与消费者”的问题

线程池:其实就是⼀个容纳多个线程的容器,其中的线程可以反复使⽤,省去了频繁创建线程对 象的操作,⽆需反复创建线程⽽消耗过多资源

合理利⽤线程池能够带来三个好处:

1. 降低资源消耗。减少了创建和销毁线程的次数,每个⼯作线程都可以被重复利⽤,可执⾏多个任务。

2. 提⾼响应速度。当任务到达时,任务可以不需要的等到线程创建就能⽴即执⾏。

3. 提⾼线程的可管理性。可以根据系统的承受能⼒,调整线程池中⼯作线线程的数⽬,防⽌因为消耗过多的内存,⽽把服务器累趴下(每个线程需要⼤约1MB内存,线程开的越多,消耗的内存也就越⼤,最后死机)。

使⽤线程池中线程对象的步骤:

1. 创建线程池对象。

2. 创建Runnable接⼝⼦类对象。(task)

3. 提交Runnable接⼝⼦类对象。(take task)

4. 关闭线程池(⼀般不做)。

Executors 类中有个创建线程池的⽅法如下:

public static ExecutorService newCachedThreadPool() 创建一个根据需要创建新线程的线程池,但在可用时将重新使用以前构造的线程。

public static ExecutorService newFixedThreadPool(int nThreads) :返回线程池对象。(创建的是有界线程池,也就是池中的线程个数可以指定最⼤数量)

static ExecutorService newSingleThreadExecutor() 创建一个使用从无界队列运行的单个工作线程的执行程序。  

static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) 创建一个线程池,可以调度命令在给定的延迟之后运行,或定期执行。  

public Future submit(Runnable task) :获取线程池中的某⼀个线程对象,并执⾏

public void shutdown() 启动有序关闭,其中先前提交的任务将被执行,但不会接受任何新任务。

ScheduledExecutorService类独有的延迟:public ScheduledFuture schedule(Runnable command, long delay, TimeUnit unit) 创建并执行在给定延迟后启用的单次操作。  

  Thread 和 Runnable 的区别

如果⼀个类继承 Thread,则不适合资源共享。但是如果实现了 Runable 接⼝的话,则很容易的实现资源共享。

总结:实现 Runnable 接⼝⽐继承 Thread 类所具有的优势:

1. 适合多个相同的程序代码的线程去共享同⼀个资源。

2. 可以避免 java 中的单继承的局限性。

3. 增加程序的健壮性,实现解耦操作,代码可以被多个线程共享,代码和线程独⽴。

4. 线程池只能放⼊实现 Runable 或 Callable 类线程,不能直接放⼊继承 Thread 的类。

Run方法任何时刻都有可能被打断

优先级只是提升了这个线程的执行概率

GC -> 垃圾回收机制

setDaemon(true):如果 true ,将此线程标记为守护线程。设置守护线程,所有的”前置”线程都结束了,守护线程也结束(当运行的唯一线程都是守护进程线程时,Java虚拟机将退出。)

线程通信  sleep()等待 带着锁 wait()等待会释放锁(别的等待会释放锁)

join(long millis)等待最多millis毫秒(系统过去millis毫秒)后无论之前线程有没有结束,都开始

线程同步:

1. 同步代码块:synchronized 关键字可以⽤于⽅法中的某个区块中,表示只对这个区块的资源实⾏互斥访问

2. 同步⽅法:使⽤ synchronized 修饰的⽅法,就叫做同步⽅法,保证A线程执⾏该⽅法的时候,其他线程只能在⽅法外等着。

3. 锁机制:java.util.concurrent.locks.Lock 机制提供了⽐synchronized代码块和synchronized⽅法更⼴泛的锁定操作,同步代码块/同步⽅法具有的功能Lock都有,除此之外更强⼤,更体现⾯向对象。

Lock锁也称同步锁,加锁与释放锁⽅法化了,如下:

public void lock() :加同步锁。 public void unlock() :释放同步锁。

线程通信: 等待唤醒机制   wait/notify 就是线程间的⼀种协作机制。

调⽤wait和notify⽅法需要注意的细节:

1. wait⽅法与notify⽅法必须要由同⼀个锁对象调⽤。因为:对应的锁对象可以通过notify唤醒使⽤同⼀个锁对象调⽤的wait⽅法后的线程。

2. wait⽅法与notify⽅法是属于Object类的⽅法的。因为:锁对象可以是任意对象,⽽任意对象的所属类都是继承了Object类的。

3. wait⽅法与notify⽅法必须要在同步代码块或者是同步函数中使⽤。因为:必须要通过锁对象调⽤这2个⽅法。

等待唤醒机制其实就是经典的“⽣产者与消费者”的问题

线程池:其实就是⼀个容纳多个线程的容器,其中的线程可以反复使⽤,省去了频繁创建线程对 象的操作,⽆需反复创建线程⽽消耗过多资源

合理利⽤线程池能够带来三个好处:

1. 降低资源消耗。减少了创建和销毁线程的次数,每个⼯作线程都可以被重复利⽤,可执⾏多个任务。

2. 提⾼响应速度。当任务到达时,任务可以不需要的等到线程创建就能⽴即执⾏。

3. 提⾼线程的可管理性。可以根据系统的承受能⼒,调整线程池中⼯作线线程的数⽬,防⽌因为消耗过多的内存,⽽把服务器累趴下(每个线程需要⼤约1MB内存,线程开的越多,消耗的内存也就越⼤,最后死机)。

使⽤线程池中线程对象的步骤:

1. 创建线程池对象。

2. 创建Runnable接⼝⼦类对象。(task)

3. 提交Runnable接⼝⼦类对象。(take task)

4. 关闭线程池(⼀般不做)。

Executors 类中有个创建线程池的⽅法如下:

public static ExecutorService newCachedThreadPool() 创建一个根据需要创建新线程的线程池,但在可用时将重新使用以前构造的线程。

public static ExecutorService newFixedThreadPool(int nThreads) :返回线程池对象。(创建的是有界线程池,也就是池中的线程个数可以指定最⼤数量)

static ExecutorService newSingleThreadExecutor() 创建一个使用从无界队列运行的单个工作线程的执行程序。  

static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) 创建一个线程池,可以调度命令在给定的延迟之后运行,或定期执行。  

public Future submit(Runnable task) :获取线程池中的某⼀个线程对象,并执⾏

public void shutdown() 启动有序关闭,其中先前提交的任务将被执行,但不会接受任何新任务。

ScheduledExecutorService类独有的延迟:public ScheduledFuture schedule(Runnable command, long delay, TimeUnit unit) 创建并执行在给定延迟后启用的单次操作。  

  

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1032429.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号