多线程的存在的现实意义:计算机CPU的运行速度远远高于I/O的原型速度,为了更好的利用CPU,所以开辟了多线程机制,使用CPU时间分片这种方法来提高CPU的使用率。
- 多线程的创建
- 多线程状态的检测和控制
- 多线程运行顺序
- 守护线程
1.多线程的创建
这个大家都很熟悉,有两种方法,第一种是继承Thread类;第二种是实现Runnable接口的对象作为Thread类的构造参数,创建线程。
第一种方法创建多线程:
public class MyThread extends Thread{
@Override
public void run() {
System.out.println(Thread.currentThread().getName());
}
}
第二种方法创建多线程:
public class RunThread implements Runnable{
@Override
public void run() {
System.out.println("thread interface way");
}
}
多线程的测试方法:
public static void main(String[] args) {
System.out.println(Thread.currentThread().getName());
MyThread mt=new MyThread();
Thread rnth=new Thread(new RunThread());
rnth.start();
mt.start();
}
Note:这两种创建方法之间的异同点可以在代码中仔细观察获得。运行多次之后,会发现console中显示的结果是乱序的。这个是多线程中存在的现象。
2.多线程状态的检测和控制
a.多线程状态信息的获取
Thread.currentThread()这个会返回当前正在运行这个方法的线程对象,通过线程对象得它的信息和修改它的信息。
Thread.currentThread().isAlive()判断当前正在运行这行代码的线程是不是处于活动状态。
isAlive()是判断线程对象是不是处于活动状态。
interrupted()测试线程对象是否已经是中断状态,执行后具有将状态标志置清除为false的功能
isInterrupted()测试线程对象是否已经中断,但是不清除状态标志
这些都是获取当前线程信息的方法
b.多线程状态的控制
sleep(long)是让调用这个方法的线程对象休眠long的毫秒数,要用try ... catch包裹
中止多线程的方法 ,使用异常进行中止是最友好的方式:
@Override
public void run(){
System.out.println(Thread.currentThread().getName());
System.out.println(Thread.currentThread().isAlive());
this.interrupt();
try {
if(Thread.currentThread().interrupted()) {
System.out.println("thread break down");
throw new InterruptedException();
}
}catch(InterruptedException e) {
System.out.println("Exception happen when thread break down !");
e.printStackTrace();
}
System.out.println(Thread.currentThread().getId());
}
这种方式是有效的,同时异常可以向上抛出通知上层的调用。线程中止并不是立即执行的,程序只是发送一个信号给线程,让线程处理相关的任务,保证数据一致性。线程在做完数据一致性的任务之后,会返回异常信息。返回异常信息的输出有可能按照代码的顺序输出的,但是也有可能不是,其中的原因与java文件的编译和执行有关。下面是执行结果
Thread-0
true
thread break down
Exception happen when thread break down !
9
java.lang.InterruptedException
at com.minshenglife.MyThread.run(MyThread.java:14)
3.多线程运行顺序
yield()方法是线程对象放弃占有的cpu资源,重新在线程之间分配cpu资源。线程对象放弃时时间不确定,有可能马上放弃,有可能等一段时间,放弃之后有可能立即又获得cpu资源。
setPriority()方法是设置线程对象的优先级,取值范围1到10的整数。当两个线程之间的优先级差距很大时,高优先级的优先执行,执行速度较快,但是线程执行完的时间与调用的顺序无关。当优先级差距不大或者是没有差距时,执行顺序是随机的。
4.守护线程
守护线程叫做Daemon,可以看做是用户线程的基础维护线程,提供一些公共的处理以及公共的信息。例如时钟服务和垃圾回收等。
将线程对象设置为守护线程的方法是setDaemon(true) 。