0-并发编程-多线程

在这里插入图片描述
JAVA 线程实现/ 创建
1.继承 Thread 类

Thread 类本质上是实现了 Runnable 接口的一个实例,代表一个线程的实例。启动线程的唯一方
法就是通过 Thread 类的 start()实例方法。start()方法是一个 native 方法,它将启动一个新线程,并执行 run()方法。

public class MyThread extends Thread {
        public void run() {
            System.out.println("MyThread.run()");
        }
    }
    MyThread myThread1 = new MyThread();
    myThread1.start();
  1. 实现 Runnable 接口

如果自己的类已经 extends 另一个类,就无法直接 extends Thread,此时,可以实现一个Runnable 接口

public class MyThread extends OtherClass implements Runnable {
    public void run() {
        System.out.println("MyThread.run()");
    }
}

3.实现 Callable 接口

执行Callable 任务后,可以获取一个 Future 的对象,在该对象上调用 get 就可以获取到 Callable 任务返回的
Object 了

public class CallableThreadTest implements Callable<Integer> {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        CallableThreadTest ctt = new CallableThreadTest();
        FutureTask<Integer> ft = new FutureTask<>(ctt);
        new Thread(ft, "有返回值的线程").start();
        System.out.println("子线程的返回值" + ft.get());
    }
    @Override
    public Integer call() {
        int i;
        for (i = 0; i < 10; i += 2) {
            System.out.println(Thread.currentThread().getName() + " " + i);
        }
        return i;
    }
}
  1. 基于线程池的方式
ExecutorService threadPool = Executors.newFixedThreadPool(10);
while(true) {
        threadPool.execute(new Runnable() { // 提交多个线程任务,并执行
            @Override
            public void run() {
             System.out.println(Thread.currentThread().getName() + " is running ..");
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
    }
}

线程池
一般的线程池主要分为以下 4 个组成部分:

  1. 线程池管理器:用于创建并管理线程池
  2. 工作线程:线程池中的线程
  3. 任务接口:每个任务必须实现的接口,用于工作线程调度其运行
  4. 任务队列:用于存放待处理的任务,提供一种缓冲机制

拒绝策略:

1.AbortPolic直接抛出异常
2.CallerRunsPolicy在任务被拒绝添加后,会在调用execute方法的的线程来执行被拒绝的任务。除非executor被关闭,否则任务不会被丢弃。
3. DiscardOldestPolicy : 丢弃最老的一个请求,也就是即将被执行的一个任务
4. DiscardPolicy : 该策略默默地丢弃无法处理的任务

Java 里面线程池的顶级接口是 Executor,但是严格意义上讲 Executor 并不是一个线程池,而只是一个执行线程的工具。真正的线程池接口是 ExecutorService。

1.newCachedThreadPool

创建一个可根据需要创建新线程的线程池,但是在以前构造的线程可用时将重用它们。对于执行
很多短期异步任务的程序而言,这些线程池通常可提高程序性能。调用 execute 将重用以前构造
的线程(如果线程可用)。如果现有线程没有可用的,则创建一个新线程并添加到池中。终止并 从缓存中移除那些已有 60秒钟未被使用的线程。因此,长时间保持空闲的线程池不会使用任何资 源。

2.newFixedThreadPool

创建一个可重用固定线程数的线程池,以共享的无界队列方式来运行这些线程

3.newScheduledThreadPool

创建一个线程池,它可安排在给定延迟后运行命令或者定期地执行

4.newSingleThreadExecutor

返回一个线程池(这个线程池只有一个线程),这个线程池可以在线程死后(或发生异常时)重新启动一个线程来替代原来的线程继续执行下去

线程声明周期

在这里插入图片描述

sleep 与 与 wait 区别

  1. sleep()方法是属于 Thread 类中的。而 wait()方法,则是属于Object 类中的。
  2. sleep()方法导致了程序暂停执行指定的时间,让出 cpu 该其他线程,但是他的监控状态依然 保持者,当指定的时间到了又会自动恢复运行状态。
  3. 在调用 sleep()方法的过程中,线程不会释放对象锁。
  4. 而当调用 wait()方法的时候,线程会放弃对象锁,进入等待此对象的等待锁定池,只有针对此 对象调用 notify()方法后本线程才进入对象锁定池准备获取对象锁进入运行状态。

start 与 与 run

  1. start()方法来启动线程,真正实现了多线程运行。这时无需等待 run 方法体代码执行完毕, 可以直接继续执行下面的代码。
  2. 通过调用 Thread 类的 start()方法来启动一个线程, 这时此线程是处于就绪状态, 并没有运 行。
  3. 方法 run()称为线程体,它包含了要执行的这个线程的内容,线程就进入了运行状态,开始运 行 run 函数当中的代码。 Run 方法运行结束, 此线程终止。然后 CPU 再调度其它线程

线程让步(yield ) 会使当前线程让出 CPU 执行时间片
线程中断(interrupt) 给这个线程一个通知信号,会影响这个线程内部的一个中断标识位。这个线程本身并不会因此而改变状态(如阻塞,终止等)。
join()等待其他线程终止,当前线程转为阻塞状态,回到另一个线程结束,当前线程再由阻塞状态变为就绪状态
Object 类中的 notify() 方法,唤醒在此对象监视器上等待的单个线程

JAVA 后台线程
守护线程–也称“服务线程”,他是后台线程,它有一个特性,即为用户线程 提供 公共服务,在没有用户线程可服务时会自动离开。通过 setDaemon(true)来设置线程为“守护线程”,Daemon 线程中产生的新线程也是 Daemon 【垃圾回收线程就是一个经典的守护线程】

ThreadLocal
线程存在ThreadLocal就存在( 使用场景为 用来解决 数据库连接、Session 管理等)

-- 连接池
@Transactional
public void save{
    //用 threadlocal 为保证 2个方法获取的是同一个数据库连接
     function1();//操作数据库
     function2();;//操作数据库
}
-- sesson管理
private static final ThreadLocal threadSession = new ThreadLocal();
public static Session getSession() throws InfrastructureException {
    Session s = (Session) threadSession.get();
    try {
        if (s == null) {
            s = getSessionFactory().openSession();
            threadSession.set(s);
        }
    } catch (HibernateException ex) {
        throw new InfrastructureException(ex);
    }
    return s;
}

ThreadLocalMap (线程的一个属性),每个线程中都有一个自己的 ThreadLocalMap 类对象

进程调度算法

1.优先调度算法
a) 先来先服务调度算法 FCFS
b)短作业(进程)优先调度算法 SFJ(SPF)
2.高优先权优先调度算法
3.基于时间片的轮转调度算法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值