java多线程(一) 基础理论与执行状态

java多线程(一) 基础理论与执行状态

*进程与线程的区别

进程代表着一个应用(程序),是操作系统资源分配的最小单位.线程是进程的组成部分,有了进程才有线程,并且一个进程至少拥有一个线程.举个例子:建造房子是一个进程的话,建造房子至少需要一个人,每个人就是一个线程,如果有多个人,那么每个人可以干相同的事情,也可以干不同的事情,可以同一时间一起做事情(同时要结合后面的并行与并发的概念,这里的同时指的是并发而不是并行),也可以分开时间做事情.

* 并行与并发:

现在个人电脑都是单CPU,一个CPU同一时间只能做一件事情,两个CPU可以同时做两件事情.再拿做房子打比方,如果两个CPU,就可以让两个人一个刷墙一个铺地板,一个时间点,有两个事情在做,这个情况就是并行.单CPU(大多数人的电脑)是并发执行,再打比方,两个事情,刷墙跟铺地板,我一个人(单CPU)做着两个事情,我一边刷墙,一边铺地板,同一个时间点我只能做一件事情,不是刷墙就是铺地板,但是如果我以非常快的速度,人眼看不出来的速度,一下刷墙,一下铺地板的去做事情,在外人眼中,我在做两件事情,实际同一时间点,我只在做一件事情,这就是并发执行,CPU以非常快的速度不停地在线程中切换,一个时间点,CPU只会执行一个线程.
多线程就是为了并发的执行多件事情,比如浏览网页,如果单线程,那么只能有一个人浏览,多线程的话就可以多人去浏览.

* java多线程的创建:

无返回值:
两种方式:一种是继承Thread类,一种是实现Runnable接口.这两种方式的区别在于,继承Thread类是为了让多线程做不同的事情,实现Runnable接口是为了让多线程做同一件事情,java基础好的也会比较容易理解,java中继承类(抽象类)是一种模板设计模式,而实现接口是为了统一规范.


   //继承Thread类的方式
public  class Thread1 extends Thread {
    @Override
    public void run() {
       //要做的逻辑
    }
}

   //实现Runnable的方式
public  class Thread2 implements Runnable { 
   //只有一个run()方法,所以可以用lambda表达式
    @Override
    public void run() {
       //逻辑
    }
}

上面就是最简单的通过无返回值两种方式去创建线程,重写/实现的run方法是需要线程做的任务,下面看一下如何调用线程.

   public static void main(String[] args) {
       //通过继承Thread的方式
        Thread1 thred1= new Thread1 ();
        thred1.start();
        
        //通过实现Runnable的方式
        Thread2 Thread2 = new Thread2 ();
        new Thread(Thread2).start();
    }

上方实现Runnable的方式其实Thread2并不是线程,而是Thread的target(私有变量名),只是Thread去调用它的run方法去执行,真正的线程实例还是Thread,而实现Thread的方式,实例化的就是Thread1.
调用线程开始是start()方法,而不是run()方法,如果我们调用run()方法这里起不到线程的作用,只是调用了一个实例的实例方法而已
main()方法也是一个线程,是主线程,主线程中创建的Thread1是子线程,要理解主线程跟子线程,区别开类中继承的概念.主进程执行时是一步一步往下走的,当我们启动了一个线程Thread1后,main方法不会等待Thread1执行的状态,而是继续往下走,而Thread1去执行run()方法,两个进程并发执行.
有返回值:
有返回值的创建方式类似于无返回值中实现Runnable的方式,需要实现Callable<泛型>接口,实现call()方法

public  class Thread3 implements Callable<Integer> {
  
 //只有一个call()方法所以可以用lambda表达式
    @Override
    public Integer call() throws Exception {
        //逻辑
        return 1;
    }

    public static void main(String[] args) {
        FutureTask<Integer> futureTask = new FutureTask<Integer>(new Thread3());//传入Callable实现类
        new Thread(futureTask).start();
        try {
            Integer integer = futureTask.get();//获取返回值
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

}

代码中的泛型,必须与返回值一致. futrueTask.get()方法就是获取返回值.

* 线程执行状态

在这里插入图片描述

·新建态:new 出一个线程
·就绪态:调用了start() ,start方法只能是新建的线程去调用,不然就会异常
·运行态:调用了run()方法
·阻塞态:等待执行的过程,如:调用了spleep(毫秒)方法(如果是继承Thread类,直接可以用sleep()),或者是线程失去CPU执行权,并且等待CPU切回来的过程.如果实现了Runnable,使用Thread.currentThread().sleep(毫秒);
·死亡态:线程异常或者run()执行结束,线程死亡后就永久死亡,不可调用start()方法

start()方法之所以跟run()方法在不同状态是因为,调用了start方法后并不是马上执行run方法,start只是告诉jvm,我这个线程已经可以运行了,至于什么时候运行(run()),要看jvm的调度.
开始执行后,线程一直在运行与阻塞状态之间切换(结合并发的概念去理解)

java多线程(一) 基础理论与执行状态
java多线程(二) 控制线程与线程同步
java多线程(三) 线程通信与线程池

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值