线程进程专题复习 创建线程的四种方式

印象笔记地址:https://app

线程和进程专题

进程是资源分配的基本单位,线程是调度的基本单位。

线程依赖于进程,不能独立存在。

创建线程的4种方式总结:

1.创建线程的第一种方式:继承Thread类

(1)创建一个类继承Thread类,重写run()方法,将所要完成的任务代码写进run()方法中;

(2)创建Thread类的子类的对象;

(3)调用该对象的start()方法,该start()方法表示先开启线程,然后调用run()方法;

注意:不是创建了线程.start()就直接运行,而是 要等待时间片轮转

2.创建线程的第二种方式:实现Runable接口

(1)创建一个类并实现Runnable接口

(2)重写run()方法,将所要完成的任务代码写进run()方法中

(3)创建实现Runnable接口的类的对象,将该对象当做Thread类的构造方法中的参数传进去

(4)使用Thread类的构造方法创建一个对象,并调用start()方法即可运行该线程

3.创建线程的第三种方式:实现Callable接口

(1)创建一个类并实现Callable接口

(2)重写call()方法,将所要完成的任务的代码写进call()方法中,需要注意的是call()方法有返回值,并且可以抛出异常

(3)如果想要获取运行该线程后的返回值,需要创建Future接口的实现类的对象,即FutureTask类的对象,调用该对象的get()方法可获取call()方法的返回值

  (4)使用Thread类的有参构造器创建对象,将FutureTask类的对象当做参数传进去,然后调用start()方法开启并运行该线程。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
  ExecutorService es = Executors.newFixedThreadPool(3);
    Callable<Integer> task1 = new MyTask1();
    Callable<Integer> task2 = new MyTask2();
    Future<Integer> f1 = es.submit(task1);
    Future<Integer> f2 = es.submit(task2);
    Integer result1 = f1.get();

    Integer result2 = f2.get();
      System.out.println(result1 +result2);
}

class MyTask1 implements Callable<Integer> {
    @Override
    public Integer call() throws Exception {
        Integer sum = 0;
        for (int i = 1; i <= 50; i++) {
            sum += i;
        }
        return sum:

    }

4.创建线程的第4种方式:通过线程池

(1)使用Executors类中的newFixedThreadPool(int num)方法创建一个线程数量为num的线程池

(2)调用线程池中的execute()方法执行由实现Runnable接口创建的线程;调用submit()方法执行由实现Callable接口创建的线程

(3)调用线程池中的shutdown()方法关闭线程池

常用的接口:

  • Excutor(java.util.concurrent包下):线程池的顶级接口
  • ExcutorService:线程池接口,继承了Excutor接口 可通过submi t (Runnable task) 提交任务代码。
  • Excutors:线程池工具类,工厂类,可用于生成线程池对象

线程的基本状态:

阻塞状态:等待某个监视器所标记的状态

无限期等待状态:无限期地等待另一个线程来执行某一 特定操作的线程处于 这种状态(等待唤醒)。

sleep方法与wait方法的区别,带时间参数时有什么区别?

sleep()是线程的静态方法,但它并不释放对象锁。

wait()方法使当前线程暂停执行并释放对象锁标志,让其他线程可以进入Synchronized数据块,当前线程被放入对象等待池中。