线程池,Callable,Lock

复习

线程安全问题

原因 : 多个线程同时操作同一个数据导致的

解决思路 : 保证同时只能有一个线程操作数据

解决方案 :

方案一 : 同步代码块

语法

synchronize(锁对象){
    要同步的代码
}

注意 :

1.任何一个类的对象都可以作为锁对象

int a = 11;可以 char c = 'a';可以

Student stu = new Student();stu也可以

2.保证多个线程的锁对象是同一个对象

方案二 : 同步方法

语法

访问权限修饰符 synchronize 返回值类型 方法名(形参列表){
    方法体
}

注意 :

1.同步方法的锁对象就是调用该方法的对象,简称this 2.保证多个线程的锁对象是同一个对象(同一个对象调用)

方案三 : 同步静态方法

语法 :

访问权限修饰符 synchronize static 返回值类型 方法名(形参列表){
    方法体
}

注意 :

1.同步静态方法的锁对象是该类的类对象 2.保证多个线程的锁对象是同一个对象

类对象 : 当类被加载时会生成一个对应的对象,该对象包含该类的所有信息,如属性,方法,构造函数,类名,父类,实现的接口,所在的包等所有信息,该对象被称为该类的类对象.一个类只有一个类对象

死锁 (主动规避)

原因 : 多个线程互相抢夺对方需要的锁资源

如何避免 : 尽量不在同步中使用同步

线程间通讯

注意 :

1.线程间通讯的方法由Object提供

2.必须在同步中使用

3.必须使用所在同步的锁对象调用 (用锁对象调用方法)

提供的方法

notify() :

随机唤醒一个线程,使用同一个对象进行休眠的线程

notifyAll() :

唤醒所有线程,使用同一个对象进行休眠的线程

wait() :

无限期休眠

wait(int ms) :

有限期休眠 ms : 毫秒

wait(int ms,int ns) :

有限期休眠 ns : 纳秒

wait和sleep的区别 :

1.wait在休眠期间会释放所持有的锁资源 ,sleep不会

2.wait必须在同步中使用,sleep可以在任何一处使用

3.wait必须使用锁对象调用,sleep使用Thread类或Thread的子类对象调用

4.wait由Object提供,sleep由Thread提供

生产者与消费者模式

设计模式主要是编程人员对特定问题总结出的最优解决思路

主要解决的是工厂的进销存业务

今日

线程池 (重点)

作用 : 优化线程

为什么优化

一个线程大约占1MB的运行内存

大量创建线程时可能会导致内存溢出

大量的创建线程也导致,需要对象线程频繁创建与回收

优化思路(或想法)

用空闲的线程执行新的任务 (线程的复用)

设计一个容器来管理线程的创建,回收,复用等

(注意 : java中已经有线程池来实现以上操作)

线程池的体系结构

构造函数

public ThreadPoolExecutor(int corePoolSize,
                           int maximumPoolSize,
                           long keepAliveTime,
                           TimeUnit unit,
                           BlockingQueue<Runnable> workQueue,
                           ThreadFactory threadFactory,
                           RejectedExecutionHandler handler)

corePoolSize : 核心线程数,线程池中最少有几个线程

maximumPoolSize : 最大线程数,线程中最多可以容纳几个线程

keepAliveTime : 销毁时间,当线程执行完任务后,多久销毁

unit : 时间单位

workQueue : 存储执行的线程任务的集合(队列形式)

threadFactory : 创建线程

handler : 优化线程,使其线程复用的算法

Excutors

作用 : 创建线程池

ThreadPoolExecutor过于麻烦

此时有个靓仔写了Excutors类,用来创建线程池,由上图不难看出,返回值是创建线程池的类的对象

提供的方法

1.固定线程池

特点 :

线程池中的线程数量恒定

当线程任务小于线程数量时,随机在线程池中挑选线程执行任务.

当线程任务大于线程数量,会先执行前面的任务,后等前面任务执行完毕后,使用执行完毕的线程,执行剩余任务

static ExecutorService newFixedThreadPool(int nThreads)

nThreads : 线程池中线程的数量

2.可变线程池

特点 : 线程池中的线程数量可变

static ExecutorService newCachedThreadPool()

3.单例线程池

特点 : 一个线程池中只有一个线程

static ExecutorService newSingleThreadExecutor()

4.抢占线程池(了解)

特点 : JDK1.8出现

static ExecutorService newWorkStealingPool()

5.调度线程池

特点 : 该线程池执行任务可以延迟,也可以延迟重复执行

static ScheduledExecutorService newScheduledThreadPool(int corePoolSize)

corePoolSize : 线程池中线程的数量

6.单例调度线程池

特点 : 调度线程池中只有一个线程

static ScheduledExecutorService newSingleThreadScheduledExecutor()

线程池使用

步骤 :

1.创建线程池

2.提交任务

3.关闭线程池 (注意要关闭)

调度线程池

ScheduledExecutorService

提供的方法

public ScheduledFuture<?> schedule(线程任务,
                                    long delay, TimeUnit unit)

作用 : 延迟执行

public ScheduledFuture<?> scheduleAtFixedRate(Runnable command,
                                               long initialDelay,
                                               long period,
                                               TimeUnit unit);

作用 : 延迟重复执行

1参 : 执行的任务

2参 : 延迟时间

3参 : 间隔时间

4参 : 时间单位

注意 :

间隔时间为本次任务开始时间 - 上次任务开始时间

如果上次任务执行时间>间隔时间,那么当上次任务执行完毕后,本次任务直接开始

public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command,
                                                  long initialDelay,
                                                  long delay,
                                                  TimeUnit unit);

作用 : 重复执行

1参 : 执行的任务 2参 : 延迟时间 3参 : 间隔时间=本次任务开始时间-上次任务结束时间 4参 : 时间单位

Callable

优化线程任务的

作用 : 有返回值的线程任务对象

注意 : 无法在创建Thread对象时传入,必须配合线程池使用(和线程池绑在一起的)

Lock

优化锁对象

作用 : 简化同步

对比同步

同步代码块

synchronize(锁对象){
    //进入这里就是关锁
    代码
    //同理进入这里就是开锁(释放所资源)
}

同步方法

    访问权限修饰符 synchronize 返回值类型 方法名(形参列表){
        //进入这里就是关锁
        方法
        //同理进入这里就是开锁(释放所资源)
    }

同步静态方法

    访问权限修饰符 synchronize static 返回值类型 方法名(形参列表){
        //进入这里就是关锁
        方法
        //同理进入这里就是开锁(释放所资源)
    }

Lock体系

Lock
    提供的方法:
        void lock():关锁
        void unLock():开锁
        Condition newCondition():获取锁对象
            void await():无限期休眠
            void signal():随机唤醒一个
            void signalAll():唤醒所有
    子类:
        ReentrantLock
​
ReadWriteLock
    提供的方法:
        Lock readLock():获取读锁
        Lock writeLock():获取写锁
        注意:
            读-写 互斥
            读-读 不互斥
            写-写 互斥
    子类
        ReentrantReadWriteLock
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值