线程

一、线程、进程、程序
程序: 是一段静态的代码,他是应用软件执行的基本。
进程:是程序的一次执行过程,是系统运行程序的基本单位。
线程:是比进程更小的执行单位。相当于一个任务中的一条执行路径。

进程

每个独立执行的程序都可称为一个进程。每个运行的程序都是一个进程,在一个进程中还可以有多个执行单元同时运行,这些执行单元可以可以看做是进程执行的一条条线索。

线程

每个运行的程序都是一个进程,在一个进程中还可以有多个执行单元同时运行,这些执行单元可以看作程序执行的一条线索,被称为线程。
1、线程的创建
Java提供了两种多线程实现方式,种是继承java. lang包下的Thread类,覆写Thread类的run()方法,在run()方法中实现运行在线程上的代码;另一种是实现java. lang.Runnable接口,同样是在run()方法中实现运行在线程上的代码。

2、继承Thread类创建多线程

 public class Example01 {
 
public static void main(String[] args) {

MyThread myThread= new MyThread();      / /创建MyThread实例对象

myThread.run() ;           //调用MyThread类的run()方法

 while (true) {  //该循环是 一个死循环 ,打印输出语句
 
 System.out.println("Main方法在运行");

               }
        }
}
class MyThread{ 

public void run(){

while (ttue) }该循环是一个死循环,打印输出语句

System. out. printin ("MyThread类的run0)方法在运行");

            }

      }
      
}

3、实现Runable接口创建多线程
java中只支持单继承,一个类一旦继承了某个父类就无法再继承Thread类。
Thread类提供了另一个构造方法Thread(Runnable target),其中Runnable是一个接口,他只有一个run()方法。当通过Thread(Runnable target)构造方法创建线程对象时,只需为该方法传递一个实现了Runnable接口的实例对象,这样创建的线程将调用实现了Runnable接口中的run()方法作为运行代码,而不需要调用Thread类中的run()方法。

例如:

      public class Example03 {
      
 public static void main(String[] args) {
 
MyThread myThread= new MyThread(); //创建 MyThread的实例对象

Thread thread=new Thread (myThread); //创建线程对象

thread.start() ;  //开启线程,执行线程中的run()方法

 while (true) {
 
 System.out.println("main()方法在运行");

         }
     }
}
  class MyThread implements Runnable {
  
  public void run() { //线程的代码段,当调用start()方法时,线程从此处开始执行 
  
   while (true) {
   
 System.out .println ("MyThread类的run()方法在运行");

           }
           
        }
        
 }

4、实现Runnable接口相对于继承Thread类来说,有如的好处:

①适合多个相同程序代码的线程去处理同一个资源的情况,把线程同程序代码、数据有效的分离,很好地体现了面向对象的设计思想。

②可以避免由于Java的单继承带来的局限性。在开发中经常碰到这样一种情况,就是使用一一个已经继承了某一个类的子类创建线程,由于一个类不能同时有两个父类,所以不能用继承Thread类的方式,那么就只能采用实现Runnable接口的方式。

大部分的应用程序都会采用第二种方式来创建多线程,即实现Runnable接口。

二、线程的生命周期及状态转换

当run()方法中代码正常执行完毕或者线程抛出一-个未捕获的异常(Exception)或者错误(Error)时,线程的生命周期便会结束。

线程整个生命周期可以分为五个阶段,分别是新建状态(New)、就绪状态1Runnahle)、运行状态(Bumming)阳塞状态(Bloeked) 和死亡状态(eminated),线程的不同状态表明了线程 当前正在进行的活动。

1、新建状态(New)
创建一个线程对象后,该线程对象就处于新建状态,此时它不能运行,和其他Java对象一样,仅由java虚拟机为其分配了内存,没有表现出任何线程的动态特征。

2.就绪状态(Runnable)
当线程对象调用了snt方法后,该线程就进人就绪状态(也称可运行状态),处于就诸状态的线程位于可运行油中,此时它只是具备了运行的条件,能否获得CPU的使用权开始运行.还需要等待系统的调度。

3.运行状态(Running)
如果处于就绪状态的线程获得了CPU的使用权,开始执行run()方法中的线程执行体,则该线程处于运行状态。当- 个线程启动后,它不可能直处 于运行状态(除非它的线程执行体足够短,瞬间就结束了),当使用完系统分配的时间后,系统就会剥夺该线程占用的CPU资源,让其他线程获得执行的机会。需要注意的是,只有处于就绪状态的线程才可能转换到运行状态。

4.阻塞状态(Blocked)
一个正在执行的线程在 某些特殊情况下,如执行耗时的输人/输出操作时,会放弃CPU的使用权,进人阻塞状态。线程进入阻塞状态后,就不能进入排队列。只有当引起阻塞的原因被消除后,线程才可以转人就绪状态。

 下面列举一下下线程由运行状态转换成阳塞状态的原因,以及如何从阻塞状态转换成就绪状态。

①当线程试图获取某个对象的同步锁时,如果该锁被其他线程所持有,则当前线和公进人阻塞状态.如果想从阻塞状态进人就绪状态必须得获取到其他线程所持有来的锁。

②当线程调用了一个阻塞式的IO方法时,该线程就会进人阻塞状态,如果想进入就绪状态就必须要等到这个阻塞的IO方法返回。

③当线程调用了某个对象的wait()方法时,也会使线程进入阻塞状态,如果想进入
就绪状态就需要使用notify()方法唤醒该线程。

④当线程调用了Thread的sleep(long millis)方法时,也会使线程进入阻塞状态,在这种情况下,只需等到线程睡眠的时间到了以后,线程就会自动进人就绪状态。

⑤当在一个线程中调用了另一个线程的join()方法时,会使当前线程进入阻塞状态,在这种情况下,需要等到新加人的线程运行结束后才会结束阻塞状态,进入就绪状态。

5、死亡状态(Terminated)
线程的run()方法正常执行完毕或者线程抛出一个未捕获的异常(Exception)、错误(Error),线程就进人死亡状态。一一 旦进人死亡状态,线程将不再拥有运行的资格,也不能再转换到其他状态。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值