你的位置:首页 > Java教程

[Java教程]java线程学习


一、线程的创建

  java中创建线程有两种方式:继承Thread类和实现Runnable接口。

  1.继承Thread类

  Java语言中定义了线程类Thread,用户可以通过继承Thread类,覆盖其run()方法创建自己的线程类,线程执行的代码都包含在run方法中。

  public ClassName extends Thread{

    public void run(){

    }

  }

  2.实现Runnable接口

  另一种线程的实现方式是实现Runnable接口。如果自定义的线程还要继承其他类,这时就不能采用第一种方式来创建,java语言是不支持多继承的,却可以实现多个接口,线程同样要实现Runnable接口中的run方法,线程需要执行的代码都包含在run方法中。

  Class MyThread implements Runnable{

    public void run(){

    }

  }

二、线程的启动

  继承Thread类方式的线程启动非常简单,只要创建线程类实例后调用其start()方法用来完成线程的启动。

  ClassName c = new ClassName();

  c.start();

  实现Runnable接口创建的线程首先转换为Thread类,然后调用Thread类的start()方法启动线程。

  MyThread  mt = new MyThread();

  Thread t = new Thread(mt);

  t.start();

三、线程的生命周期

  一个生命周期内的线程主要包括创建、就绪、运行、阻塞和死亡状态。

  1.创建:在线程类使用new关键字实例化之后在调用start()方法之前,线程处于创建状态。处于创建状态的线程仅仅分配了内存空间,属于生命周期的初始状态。

  2.就绪:在线程调用了start()方法后即处于就绪状态。处于就绪状态的线程具备了除CPU之外运行所需的所有资源。就绪状态线程排队等待CPU,由系统调度为其分配。

  3.运行:处于就绪状态的线程获得CPU之后即处于运行状态。处于运行状态的线程才开始正真执行线程run()方法的内容。

  4.阻塞:处于运行状态的线程如果因为某种原因不能继续执行,则进入阻塞状态。阻塞状态与就绪状态不同的是:就绪状态只是因为缺少CPU而不能执行,而阻塞状态是由于各种原因引起线程不能执行,不仅仅是缺少CPU。引起阻塞的原因解除之后,线程再次转化为就绪状态。

  5.死亡:当线程执行完run()方法的内容或被强制终止时,线程处于死亡状态,整个生命周期结束。

四、线程的调度

  1.线程的优先级:在java语言中,通过调用setPriority()方法为线程设置优先级,优先级用1~10的数字表示,数字越大,优先级越高。如:c.setPriority(1),接着再启动线程。

  2.线程休眠:对于正在执行的线程,可以调用sleep()方法使其放弃CPU进行休眠,此线程转为阻塞状态,sleep()方法包含long型的参数,用于指定线程休眠的时间,单位为毫秒。

  3.线程让步:对于正在执行的线程,可以调用yield方法使其重新排队,将CPU让给排在后面的线程,此线程转为就绪状态。yield()方法只让步给高优先级或同等优先级的线程。

  4.线程等待:对于正在执行的线程,可以调用join()方法等待其结束,然后才执行其他程序。

    如:c.start();

      c.join();

      t.start;

  等待c线程执行完成再执行t.

五、线程同步

  当多个线程操作同一个共享资源时,比如读写同一个变量,存在着资源竞争的问题。为了解决此类问题,需要使用同步机制。在java语言中,利用synchronized关键字实现线程同步。

  实例如下:

class MyThread implements Runnable{
  private int con = 0;

  @Override
  public void run() {
    test();
  }
  private void test(){
    for(int i = 0;i<10;i++){
      con++;
      Thread.yield();
      con--;
      System.out.println(con);
    }
  }
}

public class testThread {
  public static void main(String[] args) {
    MyThread t = new MyThread();
    Thread t1 = new Thread(t);
    Thread t2= new Thread(t);

    t1.start();
    t2.start();
}
}

结果如下:

0
0
0
0
0
0
1
0
0
1
0
1

调整如下:

class MyThread implements Runnable{
  private int con = 0;

  @Override
  public void run() {
    test();
  }
  private synchronized void test(){
    for(int i = 0;i<10;i++){
      con++;
      Thread.yield();
      con--;
      System.out.println(con);
    }
  }
}

public class testThread {
  public static void main(String[] args) {
    MyThread t = new MyThread();
    Thread t1 = new Thread(t);
    Thread t2= new Thread(t);

    t1.start();
    t2.start();
  }
}

输出的结果全为0.