java多线程

来源:互联网 发布:hr面试java常问的问题 编辑:程序博客网 时间:2024/05/29 10:41

1、线程的创建

java中线程的创建有两种主要方式①创建一个runnable对象r,并实现它的run()方法。然后将该runnable对象r作为参数通过new Thread(r)语句创建新的线程②直接通过new Thread()来创建新线程,但要在其中实现run()方法。(能够这样做是因为Thread类也实现了runnable接口。)

下面还引用《Thinking in Java》中的代码来解释一下,以注释为重点就好,其他多余代码可以忽略!

public class LiftOff implements Runnable //该类实现Runnable接口{  protected int countDown = 10;   private static int taskCount = 0;  private final int id = taskCount++;  public LiftOff() {}  public LiftOff(int countDown) {    this.countDown = countDown;  }  public String status() {    return "#" + id + "(" +      (countDown > 0 ? countDown : "Liftoff!") + "), ";  }  public void run() {                 //Runnable必须实现的方法run();    while(countDown-- > 0) {      System.out.print(status());      Thread.yield();                //①    }  }}

①yield()方法:若有与当前线程优先级相同的线程可运行,那么当前线程进入可运行线程池,一个同优先级的线程运行。如果没有与当前线程优先级相同的线程可运行,那么将什么也不做。

public class BasicThreads {  public static void main(String[] args) {    Thread t = new Thread(new LiftOff());//以runnable对象为参数创建线程    t.start();//start()方法开始线程,即:调用runnable对象的run()方法    System.out.println("Waiting for LiftOff");  }}
注意,在start开始线程之后,程序会继续向下行语句执行。这是因为main()函数也对应了一个线程。

--------------------------------------------------------以上是线程的第一种创建方式-----------------------------------------------------

--------------------------------------------------------以下是线程的第二种创建方式-----------------------------------------------------

public class ThreadTest2 {    public static void main(String args[ ]){Hello t1 = new Hello( );Hello t2 = new Hello( );t1.start( );t2.start( );}}class Hello extends Thread{//继承了Thread类的类    int i ;    public void run( ){  //重写run()方法while( true){System.out.println("Hello"+i++);if (i==5)  break ;}    }  }

没什么好说的~~

总结一下常用的Thread构造方法

public Thread();    public Thread(Runnable r);      public Thread(Runnable r,String name);     public Thread(String name);

--------------------------------------------------------以下是线程的第三种创建方式-----------------------------------------------------

public class SelfManaged implements Runnable {  private int countDown = 5;  private Thread t = new Thread(this);//Thread对象  public SelfManaged() { t.start(); }  public String toString() {    return Thread.currentThread().getName() +      "(" + countDown + "), ";  }  public void run() {    while(true) {      System.out.print(this);      if(--countDown == 0)        return;    }  }  public static void main(String[] args) {    for(int i = 0; i < 5; i++)      new SelfManaged();  }} 
以上代码创建的是一个被称为自管理Runnable的类,不是什么高难度的东西,只是一种编程技巧。类中包含一个Thread的对象,利用this指针传入自身(Runnable对象)进行了初始化。在构造函数中调用start()方法启动线程。这个程序有一个缺陷:当构造器还没结束时,线程可能就已经启动了,这意味着线程可能操作一个不稳定的对象。

补充:创建线程还可以使用内部类的方式。

3、线程休眠

public class SleepingTask extends LiftOff {  public void run() {    try {      while(countDown-- > 0) {        System.out.print(status());        // Old-style:        // Thread.sleep(100);//①        // Java SE5/6-style:        TimeUnit.MILLISECONDS.sleep(100);      }    } catch(InterruptedException e) {      System.err.println("Interrupted");    }  }  public static void main(String[] args) {    ExecutorService exec = Executors.newCachedThreadPool();    for(int i = 0; i < 5; i++)      exec.execute(new SleepingTask());    exec.shutdown();  }}
LiftOff是一个Runnable接口。注释②:TimUnit是SE5中引入的显示休眠方式,作用与注释①相同。

注:因为异常不能跨线程传播会main()函数,所以必须在任务内部处理异常。