(一)java 线程初步了解

线程

线程的创建

  1. 继承类 Thread,重写 public void run()
  2. 实现接口 Runnable,重写 public void run()
  3. 实现接口 Callable<V>,重写 public V call(),构建 FutureTask<V>(callable),新建线程,如 new Thread(futureTask).start(),示例:
public static void main(String[] args){
    Callable<String> callable = new Callable<>(){
        public String call(){
            Thread.sleep(500);//futureTask get() 阻塞当前线程
            return "callable";
        }
    };

    FutureTask<String> futureTask = new FutureTask<String>(callable);
    new Thread(futureTask).start();

    try{
        Thread.sleep(100);
        System.out.println(futureTask.get());
    }catch(InterruptedException | ExecutionException e){
        e.printStackTrace();
    }
}

FutureTask 实现了接口 RunnableFuture,也就是当线程调用 run()方法时,FutureTask内部调用 Callablecall(),执行后返回值通过 set(V result)保存,等待 Future 调用(或不使用)。使用 Callable 方式创建的线程有返回值可抛异常,通过 FutureTaskget() 方法获取,当线程未执行完成时,阻塞当前线程直到子线程完成并返回结果,也可使用 get(long timeout, TimeUnit unit) 设置超时时间,避免长时间阻塞当前线程。

线程基本属性

  • 优先级 setPriority ,0-10,10优先级最高
  • sleep() 进入休眠,不放弃所有权
  • yield() 放弃

    1.让出优先权,告诉当前正在执行的线程把运行机会给线程池中优先级相同的其他线程
    2.但不能保证当前线程有运行状态迅速转换成可运行状态
    3.只能使一个线程由运行状态转为可运行状态,而不是等待或者阻塞

  • join() 阻塞当前线程,等待线程完成,类似同步作用,join()join(0) 一致,表示无限长时间,也可传非0时间,表示等待时间长度

  • interrupt() 中断当前线程,如果线程处于wait(),join(),sleep()状态,中断标志被清除,触发 InterruptedException,如果是 I/O 操作,则触发 ClosedByInterruptException
  • stop() 停止线程,过时方法,不安全
  • isAlive() 是否存活,已启动未死亡
  • setDaemon() 设置守护线程,true:守护线程,false:用户线程,应在启动前设置,如果在守护线程中创建,该线程也是守护线程。当系统剩下所有线程都为守护线程,jvm 结束,守护线程与系统共存亡,优先级比较低,用于为系统中的其它对象和线程提供服务,参考垃圾回收器

线程的复用 – 线程池

线程的执行过程:创建(t1) -> 运行(t2) -> 销毁(t3),总时间 T = t1 + t2 + t3
如果 t1 +t3 >> t2 ,那么频繁创建新线程将会浪费时间在线程的创建和销毁,而线程池技术的出现缩短或调整 t1 t3 占用时间,同时重用已完成线程资源,减少线程的创建、销毁过程,提高工作任务的执行效率。

线程池
  • JAVA 在线程池构造中使用 Executors 默认实现了四种线程池,分别是:
    1. newFixedThreadPool(int nThreads) 固定线程数量线程池
    2. newSingleThreadExecutor() 单工作线程池
    3. newCachedThreadPool() 缓存线程池
    4. newScheduledThreadPool(int corePoolSize)可定时、周期运行的线程池

其本质是通过一个静态工厂类 Executors 创建线程池 ThreadPoolExecutor 使用默认参数构造,降低线程池的使用门槛。

 public ThreadPoolExecutor(int corePoolSize,//使用核心
                           int maximumPoolSize,//线程池最大数量
                           long keepAliveTime,//线程存活时间
                           TimeUnit unit,//时间单位
                           BlockingQueue<Runnable> workQueue,//队列
                           ThreadFactory threadFactory//线程创建工厂 ) {
}
  • 使用 ThreadPoolExecutor 构造适合自己工厂的线程池
  • 通过顶级接口 Executor 中的 void execute(Runnable command)方法添加任务
  • 也可以通过接口 ExecutorService 中的 submit(...) 增加任务,其中 Callable<V> 任务使用submit(Callable<T> task)增加至线程队列,并增加了线程池的几个操作方法
    1. shoutdown() 暂停接收新任务,不会停止运行中的线程,等待队列中任务完成,关闭线程池
    2. shoutdownNow()暂停接收新任务,中断运行中的线程,将等待队列中的线程返回,清除等待队列中任务,关闭线程池
    3. awaitTermination(long timeout, TimeUnit unit)阻塞,直到所有任务完成,或发生超时,或当前线程被中断,已先发生为准,true:所有任务执行完毕,false:超时

猜你喜欢

转载自blog.csdn.net/ganfanzhou/article/details/80383786