7.25内容

线程锁对象

锁对象  lock
Lock lock = new ReentrantLock(true);
创建锁对象  默认非公平锁 加true才是公平锁

 wait  

notify   

notifyAll  

wait  sleep区别

wait是Object中定义的方法,可以有锁对象调用,让执行到该代码的线程进入到等待状态

sleep是Thread类中定义的静态方法,可以让执行到该代码的线程进入到等待状态
区别:sleep需要传入一个毫秒数,到达时间后会自动唤醒 wait不能自动唤醒,必须调用notity/notityAll方法唤醒
sleep方法保持锁状态进入等待状态 wait方法会解除锁状态,其他线程可以进入运行

ReentrantReadWriteLock类

  1. 读锁

    • 可以被多个线程同时获取,即支持共享锁。
    • 当没有写锁的时候,读锁可以被任意数量的读线程获取。
    • 当有写锁的时候,读锁会等待写锁释放后再获取。
    • 读锁是不可重入的,即同一个线程无法获取多次读锁。
  2. 写锁

    • 只能被一个线程获取,即独占锁。
    • 写锁是可重入的,即同一个线程可以多次获取写锁。
    • 当有写锁的时候,其他线程的读锁和写锁请求都会被阻塞。
    • 当有读锁的时候,写锁的请求会被阻塞,直到所有读锁都被释放。
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

public class EasyThreadC {
    public static ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
    public static ReentrantLock rl = new ReentrantLock();
    public static void method(){
        System.out.println(Thread.currentThread().getName()+"进入方法");
       Lock lock= rwl.readLock();
       lock.lock();
        System.out.println(Thread.currentThread().getName()+"加锁成功----读锁");
        try{
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        lock.unlock();
        System.out.println(Thread.currentThread().getName()+"方法结束");
    }
    public static void methodWrite(){
        System.out.println(Thread.currentThread().getName()+"进入方法");
        Lock lock= rwl.writeLock();
        lock.lock();
        System.out.println(Thread.currentThread().getName()+"加锁成功----写锁");
        try{
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        lock.unlock();
        System.out.println(Thread.currentThread().getName()+"方法结束");
    }

    public static void main(String[] args) {
        Runnable run = EasyThreadC::method;
        Runnable runWrite = EasyThreadC::methodWrite;
        Thread a = new Thread(run);
        a.start();
        Thread b = new Thread(run);
        b.start();
        Thread c = new Thread(run);
        c.start();
        Thread d = new Thread(run);
        d.start();
        Thread e = new Thread(runWrite);
        e.start();
        Thread f = new Thread(runWrite);
        f.start();
        Thread g = new Thread(runWrite);
        g.start();
        Thread h = new Thread(runWrite);
        h.start();
        System.out.println("main------end");
    }
}

   线程池

 池==重用
完成线程创建和管理,销毁线程工作
线程任务  Runable Callable
Runnable run=EasyExecuters::method;
tpe.execute(run);
Callable<String> call=EasyExecuters::methodCall;
Future<String> f=tpe.submit(call);
//tpe.submit(run);
System.out.println(f.get());//会等待线程执行完毕

//关闭线程对象
tpe.shutdown();
public class EasyExecuters {
    //线程池  池==重用
    //完成线程创建和管理,销毁线程工作
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        BlockingQueue qu = new ArrayBlockingQueue(12);
        ThreadPoolExecutor tpe = new ThreadPoolExecutor(5,10,10,
                TimeUnit.SECONDS,qu,Executors.defaultThreadFactory(),new ThreadPoolExecutor.AbortPolicy());
        //线程任务  Runable Callable
        Runnable run=EasyExecuters::method;
        tpe.execute(run);
        Callable<String> call=EasyExecuters::methodCall;
        Future<String> f=tpe.submit(call);
        //tpe.submit(run);
        System.out.println(f.get());//会等待线程执行完毕

        //关闭线程对象
        tpe.shutdown();
    }
    public static void method(){
        System.out.println(Thread.currentThread().getName()+"执行代码");
    }
    public static String methodCall() throws InterruptedException{
        System.out.println(Thread.currentThread().getName()+"执行代码Call");
        Thread.sleep(2000);
        return "callResult";
    }
}

线程池的七个参数

在Java中,线程池通常使用ThreadPoolExecutor类来实现,它有7个主要的参数:

  1. corePoolSize(核心线程数):

    • 线程池中维持的最小线程数。
    • 即使这些线程处于空闲状态,也不会被终止。
    • 在没有任务执行时,核心线程也不会被回收。
  2. maximumPoolSize(最大线程数):

    • 线程池中允许的最大线程数。
    • 当队列满了且已有的线程数小于最大线程数时,会创建新的线程来处理任务。
  3. keepAliveTime(线程存活时间):

    • 当线程池中的线程数超过corePoolSize时,多余的空闲线程在等待新任务到来时会终止。
    • keepAliveTime指定了这些空闲线程的存活时间。
  4. unit(时间单位):

    • keepAliveTime参数配合使用,指定keepAliveTime的时间单位。
    • 通常使用TimeUnit枚举类的实例,如TimeUnit.SECONDSTimeUnit.MINUTES等。
  5. workQueue(任务队列):

    • 用于保存等待执行的任务的阻塞队列。
    • 当所有corePoolSize大小的线程都在忙碌时,新任务会被添加到这个队列中。
  6. threadFactory(线程工厂):

    • 用于创建新线程的工厂。
    • 可以通过自定义线程工厂来设置线程的名称、优先级等属性。
  7. handler(拒绝处理策略):

    • 当任务无法被添加到工作队列中时,线程池会采取的饱和策略。
    • 常见的策略有:AbortPolicy(抛出RejectedExecutionException异常)、CallerRunsPolicy(在调用者线程中执行任务)、DiscardOldestPolicy(丢弃最早的未处理任务)、DiscardPolicy(静默地丢弃任务)。

线程池的四种回绝策略 

AbortPolicy  放弃该任务并会抛出一个异常
CallerrunsPolicy  调用者执行,让传递任务的线程执行此任务
DiscardOldestPolicy  放弃队列中最长的任务,不会抛出异常
DiscardPolicy    直接放弃新的任务,不会抛出异常

四种内置线程池(缓存线程池,定时运行线程池,边界线程池,单例线程池)

Java中提供了4种内置的线程池:

1. 缓存线程池(CachedThreadPool):
   - 使用`Executors.newCachedThreadPool()`创建。
   - 线程池初始没有任何线程,当有任务来时会创建新线程执行,闲置60秒后会被回收。
   - 适用于执行大量短期异步任务的场景。

2. 定时运行线程池(ScheduledThreadPool):
   - 使用`Executors.newScheduledThreadPool()`创建。
   - 线程池包含`corePoolSize`指定数量的线程,用于执行定时或周期性任务。
   - 适用于需要延迟执行或定期执行的任务。

3. 边界线程池(FixedThreadPool):
   - 使用`Executors.newFixedThreadPool()`创建。
   - 线程池大小固定,线程数等于`corePoolSize`和`maximumPoolSize`。
   - 适用于负载比较平稳的场景,可控制并发的线程数。

4. 单线程池(SingleThreadExecutor):
   - 使用`Executors.newSingleThreadExecutor()`创建。
   - 线程池中只有一个线程,任务会被顺序执行。
   - 适用于需要保证任务顺序执行的场景,例如日志记录。

线程池的工作原理  

任务放置在工作队列中
池中是否有空闲的线程,如果有就让该线程执行任务
如果没有空闲的线程,判断池中的线程数量有没有达到核心线程数
如果没有达到创捷新的线程执行任务,如果已经达到,优先在队列中存储
直到队列填满;
工作队列填满后在添加新的任务,判断是否达到最大线程数,如果没有创建新的线程执行任务
知道填满最大线程数
已经填满的最大线程数,队列也已经填满,没有空闲的线程,就执行回绝策略
线程池中的线程达到(超过)核心线程数,超出的数量会根据存活时间,进行销毁,直到数量达到核心线程数
如果线程的数量少于核心线程数,不会消亡

死锁(Deadlock)是指两个或多个线程在执行过程中,因争夺资源而造成的一种僵持状态。当线程1持有资源A并请求资源B,而线程2正持有资源B并请求资源A,这样两个线程都在等待对方释放资源,就会形成死锁。

什么是死锁

形成死锁需要满足以下4个条件:

1. **互斥条件**:资源只能被一个线程使用,不能被其他线程共享。
2. **请求和保持条件**:一个线程因请求资源而阻塞时,对已获得的资源保持不放。
3. **不可剥夺条件**:线程已获得的资源,在未使用完之前,不能被其他线程强行剥夺。
4. **循环等待条件**:存在一个线程-资源的循环等待链。

这4个条件缺一不可,只要有任何一个条件不成立,死锁就不会发生。

常见的避免死锁的方法有:

1. 破坏互斥条件:改用共享资源代替独占资源。
2. 破坏请求和保持条件:一次性申请所有需要的资源。
3. 破坏不可剥夺条件:占用资源的线程结束时主动释放资源。
4. 破坏循环等待条件:对资源加上全局排序,按序申请资源。

### 回答1: Drools是一个用于规则引擎的开源业务流程管理系统。它能够对规则进行建模、存储、查询和执行,通过规则引擎来实现流程控制和决策支持。Drools 7.25是Drools的最新版本,其文档已经推出中文版,同时也有Drools技术指南。 Drools技术指南是一本详细介绍Drools规则引擎使用的文档。它包含了Drools的体系结构、规则语言、DSL、规则文件和决策表的写法,规则引擎原理和调试技巧等方面的内容。此外,Drools技术指南也介绍了如何与Spring、Hibernate、Camel等其他技术和框架进行集成,以及如何使用Drools进行规则引擎的搭建和开发。 通过Drools技术指南,用户可以了解如何使用Drools规则引擎来实现业务流程管理、决策制定和业务规则的自动化执行,从而提高生产力和业务效率。同时,Drools技术指南也为开发人员和系统管理员提供了快速入门和深入学习Drools规则引擎的指南。无论是初学者还是有经验的开发人员,都能够从Drools技术指南中找到自己需要的内容和解决方案。 ### 回答2: Drools 是一个基于 Java 的规则引擎,它主要用于业务流程管理和事件处理。Drools 7.25 版本中的中文文档 Drools 技术指南是一个深入学习 Drools 的权威指南。这本书在理论和实践方面都非常丰富,可以帮助开发人员在使用 Drools 时深入了解规则引擎的内部机制和实现方法。该书主要分为三个部分: 第一部分介绍了 Drools 的基础知识。它包括规则引擎的概述、Drools 知识库的构建、规则的编写和调试以及相关的工具和插件。该部分通过简单的例子和代码来阐述 Drools 的各种概念和功能,帮助读者快速入门。 第二部分是关于规则的设计和优化。该部分主要重点在于如何设计和组织规则应用,以实现更好的性能和可维护性。该部分还介绍了如何使用 Drools 的高级功能,如集成规则引擎到企业应用程序中和将规则应用于大数据处理中。 第三部分是关于实践案例的介绍和分析。该部分通过实际的案例来展示如何使用 Drools 来解决实际的业务问题。该部分囊括了各种类型的案例,如物流管理、金融风控、医疗诊断等,为读者提供了一个全面的 Drools 应用实践参考。 总之,Drools 7.25 中文文档 Drools 技术指南是一本非常优秀的规则引擎学习和应用指南,它不仅适用于初学者,也适用于有一定经验的工程师和开发人员。这本书将帮助你深入了解 Drools 的内部机制和实践应用,从而更好地应对复杂的业务场景和问题。 ### 回答3: Drools是一种开源的规则引擎,可以用于构建商业规则、决策管理和复杂的业务流程中的规则引擎。Drools7.25中文文档和Drools技术指南是学习和使用Drools7.25规则引擎的重要材料。 这份文档详细地介绍了Drools7.25的安装、配置、使用和开发以及如何使用Drools7.25实现各种业务需求,如智能信息推荐系统、规则引擎规则编辑、策略设计和自动化执行等。文档的主要内容包括规则引擎基础知识、Drools规则编写、如何调试和测试规则、规则引擎应用程序开发等方面的知识。它提供了丰富的代码示例和详细的解释,可以帮助使用者快速学习和掌握Drools规则引擎的用法。 Drools技术指南则进一步深入了解Drools规则引擎的高级用法和开发技巧。该指南主要内容包括Drools语言、Drools规则流程、相关API、Drools领域特定语言以及如何优化性能等方面的内容,以及如何使用Drools规则引擎提高业务流程和规则引擎的效率和准确性。该指南提供了更加深入的技术指导和实践经验,适合有一定Drools规则引擎开发经验的开发者进行深入学习和研究。 总之,Drools7.25中文文档和Drools技术指南对于学习和开发Drools规则引擎都是非常有用的资料,对于需要使用规则引擎的公司和开发者来说,这两份文档是不可或缺的参考材料。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值