java线程

一、

Java中的线程有五种状态分别是:新建、就绪、运行、死亡、阻塞。

1、新建状态:当利用new关键字创建线程对象实例后,它仅仅作为一个对象实例存在,JVM没有为其分配线程运行资源;对处于创建状态的线程可以进行两种操作:一是启动(start)操作,使其进入可运行状态,二是终止(stop)操作,时期进入消亡状态,如果进入到消亡状态,那么,此后这个线程就不能进入其他状态,也就是说,它不再存在二里(不能进入阻塞状态)。

start方法是对应启动操作的方法,其具体功能是为线程分配必要的系统资源;将线程设置为就绪状态,从而可以使系统调度这个线程。

2、就绪状态(可运行状态):在处于新建状态的线程中调用start方法将线程的状态转化为就绪状态。这时,线程已经得到除CPU时间之外的其他系统资源,只等JVM的线程调度器按照线程的优先级对该线程进行调度,从而能够获得CPU时间片的机会。

在可运行状态可以进行多种操作,最通常的是从run()方法正常退出而使线程结束,进入消亡状态。此外,还可以有如下操作: 

     挂起操作,通过调用suspend方法来实现; //须通过恢复(resume)操作使线程回到可运行状态。 

     睡眠操作,通过调用sleep方法来实现; 

     等待操作,通过调用wait方法来实现; 

     退让操作,通过调用yield方法来实现;//把CPU控制权提前转交给同级优先权的其他线程。 

     终止操作,通过调用stop方法来实现。 

     前面三种操作都会使一个处于可运行状态的线程进入不可运行状态。

3.阻塞状态:线程能够运行,但有某个条件阻止它运行。当线程处于阻塞状态时,调度机制将忽略线程,不会分配给线程任何CPU时间。直到线程重新进入了就绪状态,它才有可能执行操作。

一个处于可运行状态的线程,如果遇到挂起 (suspend)操作、睡眠(sleep)操作或者等待(wait)操作,就会进入不可运行状态(阻塞状态)。另外,如果一个线程是和I/O操作有关的,那么,在执行I/O指令时,由于外设速度远远低于处理器速度而使线程受到阻塞,从而进入不可运行状态,只有外设完成输入/输出之后,该线程才会自动回到可运行状态。线程进入不可运行状态后,还可以再回到可运行状态。通常有三种途径 使其恢复到可运行状态。 

     一是自动恢复。通过睡眠(sleep)操作而进入不可运行状态的线程会在过了指定睡眠时间以后自动恢复到可运行状态;由于I/O阻塞而进入不可运行状态的线程在外设完成I/O操作后,自动恢复到可运行状态。 

     二是用恢复(resume)方法使其恢复。 如果一个线程由于挂起(suspend)操作而从可运行状态进入不可运行状态,那么,必须用恢复(resume)操作使其再恢复到可运行状态。 

     三是用通知(notify或notiyA11)方法使其恢复。 如果由于等待(wait)操作转入不可运行状态,那么,必须通过调用notify方法或notifyAll方法才能使其恢复到可运行状态。采用等待操作往往是由于线程需要等待某个条件变量,当获得此条件变量后,便可由notify或notifyAll方法使线程恢复到可运行状态。 

     在不可运行状态,也可由终止(stop)操作使其进入消亡状态。   

4.死亡状态:当线程的run()方法完成时就认为它死去。线程一旦死亡,就不能复生。 如果在一个死去的线程上调用start()方法,会抛出java.lang.IllegalThreadStateException异常。

线程在一定条件下,状态会发生变化。线程变化的状态转换图如下:

在当前线程中调用另一个线程的join()方法,则当前线程转入阻塞状态,直到另一个进程运行结束,当前线程再由阻塞转为就绪状态。注意:阻塞态只能进入就绪态。

常见线程名词解释

主线程:JVM调用程序main()所产生的线程。

当前线程:这个是容易混淆的概念。一般指通过Thread.currentThread()来获取的线程。由前台线程创建的线程默认也是前台线程。可以通过isDaemon()和setDaemon()方法来判断和设置一个线程是否为后台线程。

后台线程:指为其他线程提供服务的线程,也称为守护线程。JVM的垃圾回收线程就是一个后台线程。

二、

进程和线程的区别

1)每个进程都是一个独立运行的程序,拥有自己的变量,且不同进程间的变量不能共享;而线程是与西宁在进程内部的,每个正在运行的进程至少有一个线程,而且不同的线程之间可在进程范围内共享数据。也就是说进程有自己的独立的存储空间,而线程是和它所属的进程内其他线程共享一个存储空间。线程的使用可使我们能并行的处理一些事情。线程通过并行的处理给用户带来更好的使用体现,比如你使用的邮件系统(outlook、foxmail)等,你当然不希望他们在收取新邮件的时候,导致你连已经瘦小来的邮件都无法阅读,而只能等待收取邮件操作执行完毕,这正是线程的意义所在。

三、

实现一个线程的方法

多线程的实现有两种实现方法,分别是继承Thread类与实现Runable接口。

继承java.lang.Thread,并重写它的run方法,将线程的执行主体放入其中。

实现java.lang.Runnable接口,实现它的run方法,并将线程的执行主体放入其中。

这两种实现方法的区别并不大。继承Thread类的方法实现起来较简单,但是继承它的类就不能在继承别的类了;而使用Runnable接口的方式就不存在这个问题了,而且这种中实现方式将线程的主体和县城对象本身分开来,逻辑上比较清晰,所以推荐多采用这种方式。

继承Thread类实现线程的示例:

public class ThreadTest extends Thread {  

    public void run() {  

        // 在这里编写线程执行的主体  

        // do something  

    }  

}  

实现Runnable接口实现多线程的示例: 

public class RunnableTest implements Runnable {  

    public void run() {  

        // 在这里编写线程执行的主体  

        // do something  

    }  

}  



转载于:https://my.oschina.net/u/347414/blog/152562

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值