zoukankan      html  css  js  c++  java
  • 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");
        }
      
      
     }

    }

  • 相关阅读:
    pytorch的函数中的group参数的作用
    pytorch的函数中的dilation参数的作用
    resnet18全连接层改成卷积层
    Pytorch实现UNet例子学习
    MyEclipse中出现Address already in use:JVM_Bind:8080
    为SQL数据库创建登录名和密码
    集合体系
    排序算法及其java实现
    java泛型通配符?
    Arrays.asList的用法
  • 原文地址:https://www.cnblogs.com/feixue/p/2408183.html
Copyright © 2011-2022 走看看