个人学习总结一Java的多线程

多线程

一、多线程概述
1、 进程
        是一个正在执行的程序。
        每一个进程执行都有一个执行顺序。该顺序是一个执行路径,或者叫一个控制单元。
2、线程
         就是进程中的一个独立的控制单元。线程在控制着进程的执行。只要进程中有一个线程在执行,进程就不会结束。
        一个进程中至少有一个线程。
3、多线程
        在java虚拟机启动的时候会有一个java.exe的执行程序,也就是一个进程。该进程中至少有一个线程负责java程序的执行。而且这个线程运行的代码存在于main方法中。该线程称之为主线程。JVM启动除了执行一个主线程,还有负责垃圾回收机制的线程。像种在一个进程中有多个线程执行的方式,就叫做多线程。
4、多线程存在的意义
        多线程的出现能让程序产生同时运行效果。可以提高程序执行效率。
         例如:在java.exe进程执行主线程时,如果程序代码特别多,在堆内存中产生了很多对象,而同时对象调用完后,就成了垃圾。如果垃圾过多就有可能是堆内存出现内存不足的现象,只是如果只有一个线程工作的话,程序的执行将会很低效。而如果有另一个线程帮助处理的话,如垃圾回收机制线程来帮助回收垃圾的话,程序的运行将变得更有效率。
5、计算机CPU的运行原理
         我们电脑上有很多的程序在同时进行,就好像cpu在同时处理这所以程序一样。但是,在一个时刻,单核的cpu只能运行一个程序。而我们看到的同时运行效果,只是cpu在多个进程间做着快速切换动作。
         而cpu执行哪个程序,是毫无规律性的。这也是多线程的一个特性:随机性。哪个线程被cpu执行,或者说抢到了cpu的执行权,哪个线程就执行。而cpu不会只执行一个,当执行一个一会后,又会去执行另一个,或者说另一个抢走了cpu的执行权。至于究竟是怎么样执行的,只能由cpu决定。
二、创建线程的方式
        创建线程共有两种方式:继承方式和实现方式(简单的说)。
1、 继承方式
        通过查找java的帮助文档API,我们发现java中已经提供了对线程这类事物的描述的类——Thread类。这第一种方式就是通过继承Thread类,然后复写其run方法的方式来创建线程。
创建步骤:
        a,定义类继承Thread。
        b,复写Thread中的run方法。
             目的:将自定义代码存储在run方法中,让线程运行。
        c,创建定义类的实例对象。相当于创建一个线程。
        d,用该对象调用线程的start方法。该方法的作用是:启动线程,调用run方法。
注:如果对象直接调用run方法,等同于只有一个线程在执行,自定义的线程并没有启动。
覆盖run方法的原因:
        Thread类用于描述线程。该类就定义了一个功能,用于存储线程要执行的代码。该存储功能就run方法。也就是说,Thread类中的run方法,用于存储线程要运行的代码。
2、 实现方式
        使用继承方式有一个弊端,那就是如果该类本来就继承了其他父类,那么就无法通过Thread类来创建线程了。这样就有了第二种创建线程的方式:实现Runnable接口,并复习其中run方法的方式。
创建步骤:
        a,定义类实现Runnable的接口。
        b,覆盖Runnable接口中的run方法。目的也是为了将线程要运行的代码存放在该run方法中。
        c,通过Thread类创建线程对象。
        d,将Runnable接口的子类对象作为实参传递给Thread类的构造方法。

         为什么要将Runnable接口的子类对象传递给Thread的构造函数?

        因为,自定义的run方法所属的对象是Runnable接口的子类对象。所以要让线程去指定对象的run方法,就必须明确该run方法所属对象。
        e,调用Thread类中start方法启动线程。start方法会自动调用Runnable接口子类的run方法。
实现方式好处:避免了单继承的局限性。在定义线程时,建议使用实现方式。


三、两种方式的区别和线程的几种状态
1、两种方式的区别
  区别一:
  a.由于子类重写了Thread类的run(), 当调用start()时, 直接找子类的run()方法
  b.构造函数中传入了Runnable的引用, 成员变量记住了它, start()调用run()方法时内部判断成员变量Runnable是否为空, 不为空则执行Runnable的run()
  区别二:
  a.继承Thread只能是单继承,如果自己定义的线程类已经有了父类,就不能再继承了
  b.实现Runnable接口可以多实现,即使自己定义线程类已经有父类可以实现Runnable接口
  总结:继承Thread的好处是:可以直接使用Thread类中的方法,代码简单
       弊端是:如果已经有了父类,就不能用这种方法
     实现Runnable接口的好处是:即使自己定义的线程类有了父类也没关系,因为有了父类也可以实现接口,而且接口是可以多实现的弊端是:不能直接使用Thread中的方法需要先获取到线程对象后,才能得到Thread的方法,代码复杂
优先使用Runnable 接口 ---- 因为java单继承,如果继承Thread 就不能继承其他类

2、线程的四种状态:
被创建:等待启动,调用start启动。
         运行状态:具有执行资格和执行权。
         临时状态(阻塞):有执行资格,但是没有执行权。
         冻结状态:遇到sleep(time)方法和wait()方法时,失去执行资格和执行权,sleep方法时间到或者调用notify()方法时,获得执行资格,变为临时状态。
         消忙状态:stop()方法,或者run方法结束。  
四.Thread类常用方法
 1.获取名字
  通过getName()方法获取线程对象的名字
 2.设置名字
  通过构造函数可以传入String类型的名字
  通过setName(String)方法可以设置线程对象的名字
 3.获取当前线程对象
  Thread.currentThread(), 主线程也可以获取
 4.休眠
  Thread.sleep(毫秒)
 5.守护
  setDaemon(), 设置一个线程为守护线程, 该线程不会单独执行, 当其他非守护线程都执行结束后, 自动退出
 6.加入
  join(), 当前线程暂停, 等待指定的线程执行结束后, 当前线程再继续
  join(int), 可以等待指定的毫秒之后继续
       sleep 使当前线程睡眠一段时间,睡眠过程中,不释放锁资源
       join 等待目标线程执行结束后,当前线程才能继续执行

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值