zoukankan      html  css  js  c++  java
  • Java并发基础:线程的创建

    线程的创建和管理:

    1.应用Thread类显式创建、管理线程

    2.应用Executor创建并管理线程。

    定义任务:

    无返回的任务:实现Runnable接口并编写run()方法。

    有响应的任务:实现Callable接口并编写call()方法。

    如下的火箭发射倒计时任务:

    public class Lunch implements Runnable {

      int countDown = 9;
      int taskCount = 0;
      int rocketNum = 9;
      final int id = taskCount++;
      final static Logger log = Logger.getLogger("lavasoft");
      Logger log1 = Logger.getLogger("lavasoft");
      Logger log2 = Logger.getLogger("lavasoft.blog");

      public Lunch(){
      }

      public Lunch(int countDown,int rocketNum){
        this.countDown=countDown;
        this.rocketNum=rocketNum;
      }

      public void status(int rocketNum){
        while(countDown>=0){
          if(countDown==0){
            log.info("火箭"+rocketNum+"发射成功!");
            countDown--;
          }else{
            log.info("火箭"+rocketNum+"将在"+countDown+"秒后发射!");
            countDown--;
        }
      }
    }
    @Override
      public void run() {
      // TODO Auto-generated method stub
        status(rocketNum);
      }

      public static void main(String args[]) throws SecurityException, IOException{

        FileHandler fileHandler = new FileHandler("C:/testlog.log");
        fileHandler.setLevel(Level.INFO);
        fileHandler.setFormatter(new MyLogHander());
        ExecutorService exec = Executors.newCachedThreadPool();// 需要多少线程创建多少线程,用多少给多少。
        ExecutorService exec2 = Executors.newSingleThreadExecutor();// 保证任意时刻任何线程中都只有唯一的任务在运行。
        ExecutorService exec3 = Executors.newFixedThreadPool(2);//指定线程数量。
        ExecutorService exec4 = Executors.newScheduledThreadPool(2);//可实现周期性或延迟任务
        log.addHandler(fileHandler);
        for(int rocketNum=1;rocketNum<10;rocketNum++){
    //用Thread类显式创建并管理线程

    Thread t1 = new Thread(new Lunch(6,rocketNum));

    t1.start();

    //用Executor类创建并管理线程
    exec.execute(new Lunch(6,rocketNum));
    exec2.execute(new Lunch(6,rocketNum));
    exec3.execute(new Lunch(6,rocketNum));
          exec4.execute(new Lunch(6,rocketNum));
          log.info("等待火箭"+rocketNum+"发射");
        }
        exec.shutdown();
      }

    }

    class MyLogHander extends Formatter{
    @Override
      public String format(LogRecord record) {
      return record.getLevel() + ":" + record.getMessage()+" ";
      }
    }

    public class Lunch implements Callable<String> {

      int countDown = 9;
      int taskCount = 0;
      int rocketNum = 9;
      final int id = taskCount++;
      final static Logger log = Logger.getLogger("lavasoft"); 
      Logger log1 = Logger.getLogger("lavasoft"); 
      Logger log2 = Logger.getLogger("lavasoft.blog");

      public Lunch(){
      }

      public Lunch(int countDown,int rocketNum){
        this.countDown=countDown;
        this.rocketNum=rocketNum;
      }

      public void status(int rocketNum){
        while(countDown>=0){
          if(countDown==0){
            log.info("火箭"+rocketNum+"发射成功!");
            countDown--;
          }else{
            log.info("火箭"+rocketNum+"将在"+countDown+"秒后发射!");
            countDown--;
        }
      }
    }
      @Override
      public String call() {
      // TODO Auto-generated method stub
        status(rocketNum);

        return "***火箭"+rocketNum+"发射完毕***";
      }

      public static void main(String args[]) throws SecurityException, IOException{

        FileHandler fileHandler = new FileHandler("C:/testlog.log"); 
        fileHandler.setLevel(Level.INFO);
        fileHandler.setFormatter(new MyLogHander()); 
        ExecutorService exec = Executors.newCachedThreadPool();// 需要多少线程创建多少线程,用多少给多少。
        ExecutorService exec2 = Executors.newSingleThreadExecutor();// 保证任意时刻任何线程中都只有唯一的任务在运行。
        ExecutorService exec3 = Executors.newFixedThreadPool(2);//指定线程数量。
        ExecutorService exec4 = Executors.newScheduledThreadPool(2);//可实现周期性或延迟任务
        log.addHandler(fileHandler);

        List<Future<String>> list = new ArrayList<Future<String>>();

        for(int rocketNum=1;rocketNum<10;rocketNum++){
    //用Thread类显式创建并管理线程

    Thread t1 = new Thread(new Lunch(6,rocketNum));

    t1.start();

    //用Executor类创建并管理线程
    exec.execute(new Lunch(6,rocketNum));
    exec2.execute(new Lunch(6,rocketNum));
    exec3.execute(new Lunch(6,rocketNum));
        Future<String> a = exec.submit(new Lunch(6,rocketNum));//call方法会返回一个Future对象,与runnable不同,将任务赋予给线程时,必须用submit方法。
        list.add(a);
        try {
          System.out.println(a.get());
        } catch (InterruptedException | ExecutionException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
        }
          log.info("等待火箭"+rocketNum+"发射");
        }
        exec.shutdown();
      }

    }

    class MyLogHander extends Formatter{
    @Override 
      public String format(LogRecord record) { 
      return record.getLevel() + ":" + record.getMessage()+" "; 
      } 
    }

    总结:

    Callable接口和Runnable接口相似,区别就是Callable需要实现call方法,而Runnable需要实现run方法;并且,call方法还可以返回任何对象,无论是什么对象,JVM都会当作Object来处理。但是如果使用了泛型,我们就不用每次都对Object进行转换了。

    Runnable和Callable都是接口

    不同之处:
    1.Callable可以返回一个类型V,而Runnable不可以
    2.Callable能够抛出checked exception,而Runnable不可以
    3.Runnable是自从java1.1就有了,而Callable是1.5之后才加上去的
    4.Callable和Runnable都可以应用于executors。而Thread类只支持Runnable.
    上面只是简单的不同,其实这两个接口在用起来差别还是很大的。Callable与executors联合在一起,在任务完成时可立刻获得一个更新了的Future。而Runable却要自己处理

      Future接口,一般都是取回Callable执行的状态用的。其中的主要方法:

    • cancel,取消Callable的执行,当Callable还没有完成时
    • get,获得Callable的返回值
    • isCanceled,判断是否取消了
    • isDone,判断是否完成

    用Executor来构建线程池,应该要做的事:

    1).调用Executors类中的静态方法newCachedThreadPool(必要时创建新线程,空闲线程会被保留60秒)或newFixedThreadPool(包含固定数量的线程池)等,返回的是一个实现了ExecutorService接口的ThreadPoolExecutor类或者是一个实现了ScheduledExecutorServiece接口的类对象。

    2).调用submit提交Runnable或Callable对象。

    3).如果想要取消一个任务,或如果提交Callable对象,那就要保存好返回的Future对象。

    4).当不再提交任何任务时,调用shutdown方法

  • 相关阅读:
    weblogic 的应用 常见问题处理 db2 链接不上(转载)
    WebLogic简单的备份和恢复
    linux 切换用户之后变成-bash-x.x$的解决方法
    weblogic迁移随手记
    生产环境下Centos 6.5优化配置 (装载)
    查看db2表空间使用率
    Linux 之 rsyslog 系统日志转发(转载)
    windows下定时利用bat脚本实现ftp上传和下载
    rsyslog同步history日志(转载)
    linux比较指令comm、diff、grep -Ff
  • 原文地址:https://www.cnblogs.com/qcxdoit/p/7268010.html
Copyright © 2011-2022 走看看