java 多线程

  在程序中使用多线程是不可避免的,java中的多线程还是相对比较容易使用的,下面简单介绍一下java中多线程的使用。

  首先,需要将我们要执行的任务实现Runnable接口并编写run()方法;其次,使用Thread类或者Executor类来驱动执行自定义的任务。这里不再写具体的程序进行详解。

  执行线程时,我们推荐使用Executor类,因为相比Thread类有以下优势:

  1. Executor可以创建不同类型的ExecutorService,例如CachedThreadPool,FixedThreadPool,SingleThreadExecutor等,通过使用FixedThreadPool可以设定产生线程的数目,从而可以一次性完成代价高昂的线程分配的工作。并且,Executor有一个shutdown()方法,调用完该方法后不再接受新提交的任务,这样可以控制某个服务接受任务的时段;
  2. 如果要取得某个线程执行的结果,需要该任务实现Callable接口并实现call()方法,而该任务的执行必须使用ExecutorService.submit()方法来调用;
  3. 一般不能捕获从线程中逃逸的异常,但是通过Executor可以捕获在线程中出现的异常。  

  Thread.yield()方法是对线程调度器切换到另一个线程的一种建议,记住,只是一种建议,不能保证它会被采纳,所以,yield()方法是不能依赖的。

  线程的优先级可以自行设置,但是多人建议不要重设线程的优先级。

   后台线程可以通过setDaemon(true)来设置,该方法必须在调用start()方法之前。当程序中所有的非后台线程都结束时,该程序中所有的后台线程也都会终止,也就是说,只要程序中还有非后台线程在运行,后台线程就不会结束。后台线程创建的所有的线程会自动设置为后台线程,在使用后台线程时,如果程序结束,即程序中所有的非后台线程都执行完毕,那么后台线程会马上停止,也就是说后台线程可能在任何一个位置被停止,这样就不能控制后台线程的结束方式,不能完成一些必要的清理工作,所以一般情况下不建议使用后台线程,可以使用非后台的Executor,因为Executor可以控制所有的任务同时关闭。

  在测试后台线程时,使用以下代码进行测试,发现当程序结束后,deamon线程还在一直运行,后来经查才发现原来是ExecutorService的问题,ExecutorService在不调用shutdown()方法之前,一直处于运行的状态,在下面的代码中如果对exec调用shutdown()方法则没有任何问题。

    

public class TestThread {

 /**
  * @param args
  */
 public static void main(String[] args) {
  // TODO Auto-generated method stub
 try{
  ExecutorService exec = Executors.newCachedThreadPool();
  for (int i = 0; i < 5; i++)
   exec.execute(new LiftOff());
 }
 catch (Exception e) {
  e.printStackTrace();
 }
 
  Thread t = new Thread(new DaemonThread());
  t.setDaemon(true);
  t.start();
  System.out.println("Waiting for LiftOff");
 }
 
 public static class DaemonThread implements Runnable {

  @Override
    public void run() {
     // TODO Auto-generated method stub
     while (true) {
      System.out.println("I am deamon thread , i am running");
      try {
         Thread.sleep(1000);
        } catch (InterruptedException e) {
         // TODO Auto-generated catch block
         e.printStackTrace();
        }
     }
    }
  
 }
 
 public static class LiftOff implements 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!") + ").";
  }
  @Override
    public void run() {
     // TODO Auto-generated method stub
     while (countDown-- > 0) {
      System.out.print(status());
      try {
         Thread.sleep(2000);
        } catch (InterruptedException e) {
         // TODO Auto-generated catch block
         e.printStackTrace();
        }
      Thread.yield();
     }
     System.out.println("lift off is over");
    }
  
  
 }

}

posted @ 2012-03-20 16:48  清清之雪  阅读(1110)  评论(0编辑  收藏  举报