zoukankan      html  css  js  c++  java
  • Java中线程的使用

    多线程的创建及启动

    一、继承Thread类创建线程子类
    1.在这子类中重写run方法,在run方法内写线程任务代码
    2.创建该子类实例,即是创建了一个线程实例
    3.调用该实例的start方法来启动该线程

    public class TestThread {
        public static void main(String[] args) {
            CurrentThread ct = new CurrentThread();
            ct.start();
        }
    
        private static class CurrentThread extends Thread {
            @Override
            public void run() {
                // TODO 重写run()方法,线程执行代码
                super.run();
            }
        }
    }


    二、建一个类去实现Runnable接口
    1.该类去实现接口的run方法,run方法内写线程任务代码
    2.创建该类实例,把该实例当作一个标记target传给Thread类,如:Thread t = new Thread(该类实例);即创建一个线程对象
    3.调用线程的star方法来启用该线程

    public class TestThread {
        public static void main(String[] args) {
            // new了一个线程类的对象出来
            CurrentThread ct = new CurrentThread();
            // 要启动一个新的线程就必须new一个Thread对象出来
            Thread thread = new Thread(ct);
            // 启动新开辟的线程,新线程执行的是run()方法,新线程与主线程会一起并行执行
            thread.start();
        }
    
        private static class CurrentThread implements Runnable {
    
            public void run() {
                // TODO 重写run()方法,线程执行代码
            }
    
        }
    }


    三 .使用Callable和Future接口创建线程。

    具体是创建Callable接口的实现类,并实现call()方法。并且有返回值

    package miye;
    
    import java.util.concurrent.Callable;
    import java.util.concurrent.FutureTask;
    
    /**
     * Callable规定的方法是call(),而Runnable规定的方法是run()
     * 实现 Callable 接口。 相较于实现 Runnable 接口的方式,方法可以有返回值,并且可以抛出异常
     * 运行Callable任务可拿到一个Future对象, Future表示异步计算的结果。 
     *      它提供了检查计算是否完成的方法,以等待计算的完成,并检索计算的结果。 
     *      通过Future对象可了解任务执行情况,可取消任务的执行,还可获取任务执行的结果。 
     *        Callable是类似于Runnable的接口,实现Callable接口的类和实现Runnable的类都是可被其它线程执行的任务。 
     *
     */
    public class TestThread {
        public static void main(String[] args) {
            CurrentThread ct = new CurrentThread();
            // 1.执行 Callable 方式,需要 FutureTask 实现类的支持,用于接收运算结果。
            FutureTask<Object> result = new FutureTask<Object>(ct);
    
            new Thread(result).start();
    
            // 2.接收线程运算后的结果
            try {
                 // FutureTask 可用于 闭锁 类似于CountDownLatch的作用,在所有的线程没有执行完成之后这里是不会执行的
                Object sum = result.get();
                System.out.println(sum);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        static class CurrentThread implements Callable<Object> {
    
            public Object call() throws Exception {
                // TODO Auto-generated method stub
                return null;
            }
    
        }
    }


    四 .线程池:


    1.获取线程池对象:
    ExecutorService service = Executors.newFixedThreadPool(2);

    2.使用线程池对象执行,并缓存线程
    MyCallable myCall = new MyCallable();
    Future<Integer> result = service.submit(myCall);
    System.out.println("获取结果:" + result.get());
    service.shutdown();//关闭线程池

    常见线程池

    CachedThreadPool()

    可缓存线程池:

    线程数无限制
    有空闲线程则复用空闲线程,若无空闲线程则新建线程
    一定程序减少频繁创建/销毁线程,减少系统开销

    创建方法:
    ExecutorService cachedThreadPool = Executors.newCachedThreadPool();


    FixedThreadPool()
    定长线程池:
    可控制线程最大并发数(同时执行的线程数)
    超出的线程会在队列中等待
    创建方法:
    ExecutorService fixedThreadPool = Executors.newFixedThreadPool(int nThreads);


    ScheduledThreadPool()
    定长线程池:
    支持定时及周期性任务执行。
    创建方法:
    //nThreads => 最大线程数即maximumPoolSize
    ExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(int corePoolSize);


    SingleThreadExecutor()
    单线程化的线程池:
    有且仅有一个工作线程执行任务
    所有任务按照指定顺序执行,即遵循队列的入队出队规则
    创建方法:
    ExecutorService singleThreadPool = Executors.newSingleThreadPool();


    3.第一种,第二种和第三种的区别:
    1).如果不需要获取线程的返回值,可以使用第一种或第二种(建议使用第二种)
    反之,如果需要获取线程的返回值,可以使用第三种。


    创建线程的三种方式的对比
    采用实现Runnable、Callable接口的方式创见多线程时,优势是:
    线程类只是实现了Runnable接口或Callable接口,还可以继承其他类。
    在这种方式下,多个线程可以共享同一个target对象,所以非常适合多个相同线程来处理同一份资源的情况,从而可以将CPU、代码和数据分开,形成清晰的模型,较好地体现了面向对象的思想。
    劣势是:
    编程稍微复杂,如果要访问当前线程,则必须使用Thread.currentThread()方法。
    使用继承Thread类的方式创建多线程时优势是:
    编写简单,如果需要访问当前线程,则无需使用Thread.currentThread()方法,直接使用this即可获得当前线程。
    劣势是:
    线程类已经继承了Thread类,所以不能再继承其他父类。

  • 相关阅读:
    Trie Tree和Radix Tree
    DataNode Layout升级解决Du操作引发的性能问题
    Write-Ahead Log(WAL)的工作原理
    YARN的共享存储服务
    AWS S3存储基于Hadoop之上的一致性保证
    简单聊聊HDFS RBF第二阶段工作近期的一些进展
    基于 Confluence 6 数据中心的 SAML 单点登录设置你的身份提供者
    基于 Confluence 6 数据中心的 SAML 单点登录设置 SSL/TLS
    Confluence 6 基于 Confluence 数据中心的 SAML 单点登录
    Confluence 6 用自带的用户管理
  • 原文地址:https://www.cnblogs.com/miye/p/9312897.html
Copyright © 2011-2022 走看看