Thread

多线程简介

    Java中的多线程在每个操作系统中的运行方式也存在差异

    Windows操作系统是多任务操作系统,它是以进程为单位的。一个进程是一个包含有自身地址的程序,每个独立执行的程序都称为进程,也就是正在执行的程序。

    一个线程则是进程中的执行流程,一个进程中可以同时包含多个线程,每个线程也可以得到一小段程序的执行时间,这样一个进程就可以具有多个并发执行的线程

实现线程的两个方式

    1.继承java.lang.Thread类

public 类名 extends Thread{
  public void run(){
    ……//方法体
  }
  public void main (String[] args){
    new 类名.start();
  }
}

    在main方法中,使线程执行需要调用Thread类中的start()方法,start()方法调用被覆盖的run()方法,若不调用start()方法,线程永远都不会启动;在主方法没有调用start()方法之前,Thread对象只是一个实例,而不是一个真正的线程。

    2.实现java.lang.Runnable接口

    若一个类需要继承其他类(非Thread类),同时还要使当前类实现多线程,那么就必须通过Runnable接口来实现了。

    实现Runnable接口的程序会创建一个Thread对象,并将Runnable对象与Thread对象相关联。

    使用Runnable接口启动新的线程的步骤如下:

        (1)建立Runnable对象。

        (2)使用参数为Runnable对象的构造方法创建Thread实例。

        (3)调用start()方法启动线程。

线程的生命周期

    线程具有生命周期,包含7种状态,分别是出生状态、就绪状态、运行状态、等待状态、休眠状态、阻塞状态和死亡状态。

    出生状态:是线程被创建时处于的状态,在用户使用该线程实例调用start()方法之前线程都处于出生状态

    就绪状态:当调用start()方法后,线程处于就绪状态(又称可运行状态)

    运行状态:当就绪状态线程得到系统资源后就进入运行状态。

    一旦线程进入可执行状态,它会在就绪与运行状态下转换,同时也有可能进入等待、休眠、阻塞、死亡状态。

    等待状态:当处于运行状态下的线程调用Thread类中的wait()方法是,该线程就进入等待状态;进入等待状态的线程必须调用Thread类中的notify()方法才能被唤醒,而notifyAll()方法是将所有处于等待状态下的线程唤醒。

    休眠状态:当线程调用Thread类中的sleep()方法时,线程就会进入休眠状态。

    阻塞状态:当一个线程在运行状态下发出输入/输出请求,该线程将进入阻塞状态,在其等待输入/输出请求结束时线程进入就绪状态。

    死亡状态:当线程的run()方法执行完毕时,线程进入死亡状态。

操作线程的方法

    1.线程的休眠

        sleep()方法需要一个参数用于指定该线程休眠的时间,改时间以毫秒为单位。

try{
  Thread.sleep(2000);
}catch(InterruptedException e){
  e.printStackTrace();
}

        由于sleep()方法的执行可能抛出InterruptedException异常,所以讲sleep()方法的调用放在try-catch块中。

    2.线程的加入

        Thread类中的join()方法。当某个线程使用join()方法加入到另外一个线程是,另一个线程会等待该线程执行完毕后再继续执行。

    3.线程的中断

        在run()方法中使用无限循环的形式,然后使用一个布尔型标记控制循环的停止。

        当线程因使用sleep或wait()方法进入了就绪状态,可以使用Thread类中的interrupt()方法是线程离开run()方法,同时结束线程。但程序会抛出InterruptedException异常,用户可以在处理该异常时完成线程的中断业务处理,如终止while循环。

    4.线程的礼让

线程的优先级

    每个线程都具有各自的优先级,线程的优先级可以表明在程序中该线程的重要性,如果有很多线程处于就绪状态,系统会根据优先级来决定首先使哪个线程进入运行状态。但这并不意味着低优先级的线程得不到运行,而只是它运行的几率比较小,如垃圾回收线程的优先级就较低。

    Thread类中包含的成员变量代表了线程的某些优先级,如Thread.MIN_PRIORITY(常数1)、Thread.MAX_PRIORITY(常数10)、Thread.NORM_PRIORITY(常数5)。其中每个线程的优先级都在1~10之间,在默认情况下其优先级都是5。每个新产生的线程都集成了父线程的优先级。

    在多任务操作系统中,每个线程都会得到一小段CPU时间片运行,在时间结束时,将轮换到另一个线程进入运行状态,这时系统会选择与当前线程优先级相同的线程予以运行。系统始终选择就绪状态下优先级较高的线程进入运行状态。

    线程的优先级可以使用setPriority()方法调整。如果使用该方法设置的优先级不在1~10之内,将产生IllegalArgumentException异常。

线程同步

    1.线程安全

        实质上线程安全问题来源于两个线程同时存取单一对象的数据。

    2.线程同步机制

        A.同步块(也被称为临界区)

            同步机制,使用synchronized关键字

            通常将共享资源的操作放置在synchronized定义的区域中,这样当其他线程也获取到这个锁时,必须等待锁被释放时才能进入该区域。

        B.同步方法

synchronized void f(){
……//方法体
}

            当某个对象调用了同步方法时,该对象上的其他同步方法必须等待该方法执行完毕后才能被执行。必须将每个能访问共享资源的方法修饰为synchronized,否则就会出错。


















猜你喜欢

转载自blog.csdn.net/qq_41661831/article/details/79299862