Java学习——多线程

多线程:让程序同时做多件事情

线程:线程是操作系统能够进行运行的最小单位,它被包含在进程之中,是进程中实际运作单位

进程:进程是程序的基本执行实体

应用场景:软件中的耗时操作、加载大量资源文件、拷贝迁移大文件

并发和并行:

并发:在同一时刻,有多个指令在单个CPU上交替执行

并行:在同一时刻有多个指令在多个CPU上同时执行

多线程的实现方式:

(1)继承Thread类的方式进行实现:编程比较简单,可以直接使用Thread类中的方法,可扩展性较差,不能继承其他的类

1.自己定义一个类继承Thread

2.重写run方法

3.创建子类对象,并启动线程

(2)实现Runnable接口的方式进行实现:编程比较简单,可以直接使用Thread类中的方法,可扩展性较差,不能继承其他的类

1.自定义一个类,实现Runnable接口

2.重写里面的run方法

3.创建此类的对象

4.创建一个Thread对象,并启动线程

(3)利用Callable接口和Future接口方式实现:扩展性强,实现该类接口的同时还可以继承其他的类,但是编程相对复杂,不能直接使用Thread类中的方法

可以获取到多线程运行的结果

1.创建一个类实现Callable接口

2.重写call(是有返回值的,表示多线程运行的结果)

3.创建该类的对象(表示多线程要执行的任务)

4.创建Future对象(管理多线程运行的结果)

5.创建Thread类对象,并启动(表示线程)

多线程中的常见成员方法:

方法名称说明
String getName()返回此线程的名称
void setName(String name)设置线程的名称
static Thread currentThread()获取当前线程的对象
static void sleep(long time)让线程休眠指定的时间,单位为毫秒
setPrioirty(int newPriority)设置线程的优先级
final int getPriority()获取线程的优先级
final void setDaemon(boolean on)设置守护线程
public static void yield()出让线程/礼让线程
public static void join()插入线程/插队线程

当其他的非守护线程执行完毕后,守护线程会陆续结束

线程的生命周期:

线程的安全问题:

同步代码块:把操作共享数据的代码锁起来

格式:

sychronized (锁){
    操作共享数据的代码;
}
特点1:锁默认打开,有一个线程进去后锁自动关闭
特点2:里面的代码全部执行完毕,线程出来后锁自动打开
细节1:sychronized要写在循环的里面
细节2:锁对象一定是唯一的

同步方法:把synchronized关键字加到方法上面

格式:

修饰符 synchronized 返回值类型 方法名(方法参数){...}

同步方法是锁住方法里面的所有代码,并且其锁对象不能自己指定(非静态this,静态是当前类的字节码文件对象)

Lock锁:

JDK5以后提供了一个新的锁对象Lock,实现比使用synchronized方法和语句可以获得更广泛的锁定操作,提供了获得锁和释放锁的方法。分别是void lock()和void unlock()。Lock是接口不能直接实例化,可以采用它的ReentrantLock来实例化。

生产者和消费者(等待唤醒机制):生产者消费者模式是一个十分经典的多线程协作的模式

生产者:生产数据

消费者:消费数据

常见方法:

方法名称说明
void wait()当前线程等待,直到被其他线程唤醒
void notify()随机唤醒单个线程
void notifyAll()唤醒所有线程

多线程的状态:

新建状态(NEW):创建线程对象

就绪状态(RUNNABLE):start方法

阻塞状态(BLOCKED):无法获得锁对象

等待状态(WAITING):wait方法

计时等待(TIME_WAITING):sleep方法

结束状态(TERMINATED):全部代码执行完毕

线程池:

以前写多线程的弊端:使用线程的时候需要创建线程,使用完毕后线程就会消失

核心逻辑:

1.创建一个线程池,线程池里面是空的

2.提交任务时,线程池会创建新的线程对象,任务执行完毕后线程归还线程池,下次再提交任务时,不需要创建新的线程,直接使用已有的线程即可

3.如果提交任务时,线程池中没有空闲线程,也无法创建新的线程,任务就会排队等待

代码实现:

1.创建线程池

Executors:线程池的工具类通过调用方法返回不同类型的线程池对象

方法名称说明
public static ExecutorService newCachedThreadPool()创建一个没有上限的线程池
public static ExecutorService newFixedThreadPool(int nThreads)创建有上限的线程池

ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(七个参数)

序号参数说明取值范围
1核心线程数量不能小于0
2最大线程数不能小于等于0,最大数量≥核心线程数量
3空闲线程最大存储时间不能小于0
4时间单位用TimeUnit指定
5任务队列不能为null
6创建线程工厂不能为null
7任务的拒绝策略不能为null

2.提交任务

线程池对象.submir(线程对象)

不断地提交任务,会有以下三个临界点:

(1)当核心线程满时,再提交任务就会排队

(2)当核心线程满,队伍满时,会创建临时线程

(3)当核心线程满,队伍满,临时线程满时,会触发任务拒绝策略

3.所有任务执行完毕,关闭线程池

线程池大小:

CPU密集型运算:最大并行数(x核y线程中的y) + 1

I/O密集型运算:最大并行数 * 期望CPU利用率 * 总时间(CPU计算时间+等待时间)/CPU计算时间

  • 9
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值