java多线程:1、多线程基础

面试:为什么要使用多线程?

  1. 一个采用了多线程技术的应用程序可以更好地利用系统资源。其主要优势在于充分利用了CPU的空闲时间片,可以用尽可能少的时间来对用户的要求做出响应,使得进程的整体运行效率得到较大提高,同时增强了应用程序的灵活性。

  2. 更为重要的是,由于同一进程的所有线程是共享同一内存,所以不需要特殊的数据传送机制,不需要建立共享存储区或共享文件,从而使得不同任务之间的协调操作与运行、数据的交互、资源的分配等问题更加易于解决。

面试:线程和进程

  • 进程:
    是指一个内存中运行的应用程序,每个进程都有一个独立的内存空间,一个应用程序可以同时运行多个进程;进程也是程序的一次执行过程,是系统运行程序的基本单位;系统运行一个程序即是一个进程从创建、运行到消亡的过程。

  • 线程:
    进程内部的一个独立执行单元;一个进程可以同时并发的运行多个线程,可以理解为一个进程便相当于一个单 CPU 操作系统,而线程便是这个系统中运行的多个任务。

  • 进程与线程的区别:

  • 进程:有独立的内存空间,进程中数据的存放空间(堆空间和栈空间)是独立的,至少有一个线程,在java程序中一个进程至少拥有两个线程。
  • 线程:堆空间是共享的,栈空间是独立的,线程消耗的资源比进程小的多

注意:

  1. 因为一个进程中的多个线程是并发运行的,那么从微观角度看也是有先后顺序的,哪个线程执行完全取决于 CPU 的调度,程序员是不能完全控制的(可以设置线程优先级)。而这也就造成的多线程的随机性。
  2. Java 程序的进程里面至少包含两个线程,主线程也就是 main()方法线程,另外一个是垃圾回收机制线程。每当使用 java 命令执行一个类时,实际上都会启动一个 JVM,每一个 JVM 实际上就是在操作系统中启动了一个 线程,java 本身具备了垃圾的收集机制,所以在 Java 运行时至少会启动两个线程。
  3. 由于创建一个线程的开销比创建一个进程的开销小的多,那么我们在开发多任务运行的时候,通常考虑创建 多线程,而不是创建多进程。

多线程的创建的五种方式

  1. 继承Thread类
public class 继承Thread类 {

    public static void main(String[] args) {
        new Demo1().start();
    }

    static class Demo1 extends Thread {
        @Override
        public void run() {
            String name = Thread.currentThread().getName();
            for (int i = 0; i < 5; i++) {
                System.out.println("name:" + name + ">>>"+i);
            }
        }
    }

}
  1. 实现Runable接口
public class 实现Runnable接口 {

    public static void main(String[] args) {
        new Thread(new Demo1()).start();
    }

    static class Demo1 implements Runnable{

        @Override
        public void run(){
            String name = Thread.currentThread().getName();
            for (int i = 0; i < 5; i++) {
                System.out.println("name:" + name + ">>>"+i);
            }
        }
    }

}

建议使用哪种?建议使用Runable接口

  • 适合多个相同的程序代码的线程去共享同一个资源。
  • 可以避免java中的单继承的局限性。
  • 增加程序的健壮性,实现解耦操作,代码可以被多个线程共享,代码和数据独立。
  • 线程池只能放入实现Runable或callable类线程,不能直接放入继承Thread的类
  1. 匿名内部类
public class 匿名内部类 {

    public static void main(String[] args) {
        new Thread(() -> {
            String name = Thread.currentThread().getName();
            for (int i = 0; i < 5; i++) {
                System.out.println("name:" + name + ">>>"+i);
            }
        }).start();
    }

}
  1. 实现juc包下的Callable接口
public class 实现Callable接口 {


    public static void main(String[] args) throws ExecutionException, InterruptedException {
        ExecutorService executorService =  Executors.newFixedThreadPool(2);
        Future<String> res = executorService.submit(new Demo());
        System.out.println("1111");
//        res.get()会阻塞当前线程,等待submit执行完成
        System.out.println(res.get());
        System.out.println("2222");
        // 线程池不会主动停止主线程的执行
//        executorService.shutdown();
    }

    static class Demo implements Callable<String> {

        @Override
        public String call() throws Exception {
            String name = Thread.currentThread().getName();
            for (int i = 0; i < 5; i++) {
                Thread.sleep(200);
                System.out.println("name:" + name + ">>>"+i);
            }
            return "ok";
        }
    }

}
  1. 线程池
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值