美文网首页
Java多线程

Java多线程

作者: Kevin_Huang54 | 来源:发表于2019-02-09 09:08 被阅读0次

    进程与线程

    • 当一个程序进入内存运行时,就变成一个进程

    • 进程就是在内存中运行的程序

    • 进程的特点:

      • 独立性:进程在内存中独立存在,拥有独立的资源,不能随意访问其他进程的地址空间
      • 动态性:程序只是磁盘上的静态指令,而进程是活动的,有自己的生命周期和活动状态
      • 并发性:多个进程可以在cpu中并发执行
    • 并行vs并发

      • 并行:多条指令在多个cpu上执行
      • 并发:多条指令快速轮换执行,达到类似同时执行的效果
    • 为什么现代操作系统可以同时执行多个任务?一边写代码、一边听音乐、还有各种后台程序管理计算机?

      • 其实并没有同时运行,只是轮流执行,采用抢占式多任务
      • 由于cpu执行速度非常快,用户感觉上就是轮流执行
    • 什么是线程

      • 线程是进程的执行单元,线程依赖于进程执行
      • 多个线程共享父进程的内存资源
      • 线程可以拥有自己的程序计数器、局部变量
      • 线程的执行是抢占式的
    • 多线程的应用

      • 浏览器同时下载多个文件
      • 服务器同时响应多个请求
      • Java虚拟机存在一个超级线程用于资源回收
    • 总结

      • 操作系统可以执行多任务,每个任务就是进程
      • 一个进程可以执行多任务,每个任务就是线程

    线程的创建方法

    • 线程的创建方法1:继承Thread类
    public class MyThread extends Thread{
        public static void main(String[] args) {
            //创建对象,通过start方法启动线程
            MyThread myThread = new MyThread();
            myThread.start();
        }
    
        @Override
        //重写run方法
        public void run() {
            System.out.println("启动线程");;
        }
    }
    
    • Thread常用方法

      • 创建Thread的时候可以在参数中指定名字
      • setName设置名字
      • getName获取名字,默认为Thread-0、Thread-1……
    • 线程的创建方法2:实现Runnable接口

    //实现Runnable接口
    public class MyThread implements Runnable{
        public static void main(String[] args) {
            //通过Thread类的有参构造器,传入实现了Runnable接口的类
            Thread myThread = new Thread(new MyThread());
            myThread.start();
        }
    
        @Override
        //实现run方法
        public void run() {
            System.out.println("启动线程");;
        }
    }
    

    可以简化为匿名类方式实现Runnable接口

    public class MyThread{
        public static void main(String[] args) {
            //通过Thread类的有参构造器,传入Runnable接口
            //用匿名类实现Runnable接口
            Thread myThread = new Thread(new Runnable() {
                @Override
                public void run() {
                    System.out.println("线程启动");
                }
            });
            myThread.start();
        }
    }
    

    由于Runnable是函数式接口,可以直接用Lambda表达式实现:

    public class MyThread{
        public static void main(String[] args) {
            //通过Thread类的有参构造器,传入Runnable接口
            //用Lambda表达式实现接口
            Thread myThread = new Thread(() -> System.out.println("线程启动"));
            myThread.start();
        }
    }
    
    • 线程的创建方法3:实现callable接口
      • 与Runnable的区别:
        --可以有返回值,通过泛型指定
        --call方法可以抛出异常
        --先用futureTask类包装callable接口,再传入Thread构造器,通futureTask可调用方法获取call方法的返回值
    public class MyThread implements Callable<String> {
        public static void main(String[] args) throws ExecutionException, InterruptedException {
            //通过FutureTask包装Callable接口
            FutureTask<String> futureTask = new FutureTask<>(new MyThread());
            //通过Thread的构造器传入Callable接口
            new Thread(futureTask).start();
            //可获取返回值
            System.out.println(futureTask.get());
        }
    
        @Override
        public String call() throws Exception {
            return "线程启动";
        }
    }
    
    • 推荐使用Runnable和Callable接口
      • 实现接口后,类还可以继承别的类
      • 多个线程可以共享同一个Runnable或Callable对象,以及这些对象内的变量

    线程的状态

    状态 说明
    新建 new创建线程后,还未调用start运行
    就绪 1、调用start后,JVM为其创建方法调用栈和程序计数器,线程试图抢占cpu资源
    2、阻塞解除后,线程试图抢占cpu资源
    运行 抢占到cpu资源,开始执行run方法
    阻塞 1、线程调用sleep方法
    2、调用了一个阻塞式IO方法
    3、执行到了wait方法,等待notify
    4、试图获取同步监视器(synchronize),但该同步监视器被其他线程占有
    死亡 run方法执行完成
    或者,线程抛出未捕获的异常
    线程状态示意图
    • 若干说明:
      • 从阻塞状态恢复后只能回到就绪状态,不能直接运行
      • 只能对新建状态的线程调用start方法,否则会抛出线程状态异常,因此不能对一个线程对象调用两次start

    控制线程

    • join线程

      • 调用join方法后,调用本线程的线程(例如main线程),会等本线程执行完再执行主线程
    Thread thread = new Thread(new MyThread()); 
    thread.start(); 
    //join后,主线程会被阻塞,等待thread线程结束后,才重新执行主线程 
    thread.join(); 
    //参数表示主程序的等待时间为1000ms,超过时间则不再等待
    thread.join(1000);
    
    • 后台线程、守护线程
      • setDaemon(true)方法
      • 必须在start之前设置
      • 当其他线程都结束后,后台线程才死亡
    • 线程睡眠sleep
      • sleep后,线程进入阻塞状态,即时没有可运行的线程,也必须等待

    相关文章

      网友评论

          本文标题:Java多线程

          本文链接:https://www.haomeiwen.com/subject/mheasqtx.html