多线程详解(一)

线程简介

进程 process 线程 thread

通常一个进程包含多个线程,当然一个进程中至少有一个线程(main方法),不然没有存在的意义!
注意:很多多线程都是被模拟出来的,真正的多线程是指多个CPU,即多核!如果是被模拟出来的,即在一个CPU的情况下,只能执行一个线程,因为CPU的切换速度很快,所以感觉不到

核心概念

  1. 线程就是一个独立的路径。
  2. 在程序运行时,即使自己没有创建线程,后台也会有多个线程,比如主线程、GC。
  3. main()被称为主线程,为系统入口,用于执行整个程序。
  4. 在一个线程中,如果开辟了多个线程,线程的运行由调度器安排,调度器与操作系统紧密相关,先后顺序是不能人为干预的。
  5. 对于同一份资源,会存在资源抢夺的问题,需要加入并发控制。
  6. 线程会带来额外的开销,比如CPU调度时间,并发控制开销。
  7. 每个线程只在自己的工作内存交互,内存控制不当会造成数据不一致

线程创建

  • 线程的创建有三种方式
  1. 继承Thread类(底层原理也实现了Runable接口)
  2. 实现Runable接口
  3. 实现Callable接口
  • 继承Thread类(一个类声明Thread类,并重写run方法,然后可以分配并调用start()方法启动子类的实例)
//创建多线程方式一 : 继承Thread类,重写run方法,启动线程
public class TestThread1 extends Thread{

    @Override
    public void run() {
        for (int i = 0; i < 20; i++) {
            System.out.println("多线程-----"+i);
        }
    }

    public static void main(String[] args) {
        TestThread1 thread = new TestThread1();
        TestThread1 testThread1 = new TestThread1();
        thread.start();
        testThread1.start();
    }
}
  • 实现Runable接口(创-静态代理)---推荐使用Runable接口,因为Java单继承的局限性
public class TestThread3 implements Runnable{

    public static void main(String[] args) {
        TestThread3 TestThread3 = new TestThread3();
        TestThread3 TestThread2 = new TestThread3();
        //创建线程对象,通过线程对象开启我们的线程代理
         Thread thread = new Thread(TestThread3);
         Thread thread1 = new Thread(TestThread2);
         thread.start();
        thread1.start();
    }


    @Override
    public void run() {
        for (int i = 0; i < 20; i++) {
            System.out.println("实现Runable接口"+i);
        }
    }
}
  • 实现Callable接口。
    步骤:
    1.实现Callable接口,需要返回值类型
    2.重写Call方法需要抛出一异常
    3.创建目标对象
    4.创建执行服务



小结

继承Thread类 --> 底层原理:静态代理,实现Runable接口

  1. 子类继承Thread类具备多线程的能力
  2. 启动线程:子类.start()
  3. 不建议使用:避免OOP单独继承的局限性

实现Runable接口

  1. 实现Runable接口具有多线程的能力。
  2. 启动线程:使用目标对象+Thread对象.start()
  3. 推荐使用:避免单继承的局限性,灵活方便,方便同一个对象被多个线程使用,同时又会造成一个新的问题,线程不安全,有并发问题

注:单继承与多继承:
单继承的局限:Java中一个类只能使用excends继承一个父类,要实现多继承,Java不允许多重继承,但是可以多层继承-->使用内部内,使用接口

上一篇:Runable接口和Thread类区别


下一篇:Java中多线程的使用(超级超级详细) Thead类的使用 3