TimeUnit类 java.util.concurrent.TimeUnit

TimeUnit是什么?

  TimeUnit是java.util.concurrent包下面的一个类,表示给定单元粒度的时间段

主要作用

  • 时间颗粒度转换
  • 延时

常用的颗粒度

TimeUnit.DAYS          //
TimeUnit.HOURS         //小时
TimeUnit.MINUTES       //分钟
TimeUnit.SECONDS       //
TimeUnit.MILLISECONDS  //毫秒

1、时间颗粒度转换 

public long toMillis(long d)    //转化成毫秒
public long toSeconds(long d)  //转化成秒
public long toMinutes(long d)  //转化成分钟
public long toHours(long d)    //转化成小时
public long toDays(long d)     //转化天

例子

import java.util.concurrent.TimeUnit;

public class TimeUnitTest {

    public static void main(String[] args) {
        //1天有24个小时    1代表1天:将1天转化为小时
        System.out.println( TimeUnit.DAYS.toHours( 1 ) );  //结果: 24
        
        //1小时有3600秒
        System.out.println( TimeUnit.HOURS.toSeconds( 1 ));  //结果3600
        
        //把3天转化成小时
        System.out.println( TimeUnit.HOURS.convert( 3 , TimeUnit.DAYS ) ); //结果是:72
    }

}

2、延时

  •  一般的写法
public class Test2 {
 
    public static void main(String[] args) {
 
        new Thread( new Runnable() {
 
            @Override
            public void run() {
                try {
                    Thread.sleep( 5 * 1000 );
                    System.out.println( "延时完成了");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();  ;
    }
     
}
  • TimeUnit 写法
import java.util.concurrent.TimeUnit;
 
public class Test2 {
 
    public static void main(String[] args) {
 
        new Thread( new Runnable() {
 
            @Override
            public void run() {
                try {
                    TimeUnit.SECONDS.sleep( 5 );
                    System.out.println( "延时5秒,完成了");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();  ;
    }
     
}

优先使用TimeUnit类中的sleep()

  TimeUnit是java.util.concurrent包下面的一个类,TimeUnit提供了可读性更好的线程暂停操作,通常用来替换Thread.sleep(),在很长一段时间里Thread的sleep()方法作为暂停线程的标准方式,几乎所有Java程序员都熟悉它,事实上sleep方法本身也很常用而且出现在很多面试中。如果你已经使用过Thread.sleep(),当然我确信你这样做过,那么你一定熟知它是一个静态方法,暂停线程时它不会释放锁,该方法会抛出InterrupttedException异常(如果有线程中断了当前线程)。但是我们很多人并没有注意的一个潜在的问题就是它的可读性。Thread.sleep()是一个重载方法,可以接收长整型毫秒和长整型的纳秒参数,这样对程序员造成的一个问题就是很难知道到底当前线程是睡眠了多少秒、分、小时或者天。看看下面这个Thread.sleep()方法:

Thread.sleep(2400000)

  粗略一看,你能计算出当前线程是等待多长时间吗?可能有些人可以,但是对于大多数程序员来说这种写法的可读性还是很差的,你需要把毫秒转换成秒和分,让我们来看看另外一个例子,这个例子比前面那个例子可读性稍微好一点:  

Thread.sleep(4*60*1000);

  这比前面那个例子已经好多了,但是仍然不是最好的,你注意到睡眠时间用毫秒,不容易猜出当前线程将等待4分钟。TimeUnit类解决了这个问题,通过指定DAYS、HOURS、MINUTES,SECONDS、MILLISECONDS和NANOSECONDS。java.utils.concurrent .TimeUnit 是Java枚举应用场景中最好的例子之一,所有TimeUnit都是枚举实例,让我们来看看线程睡眠4分钟用TimeUnit是如何使用的。

TimeUnit.MINUTES.sleep(4);  // sleeping for 4 minutes

  类似你可以采用秒、分、小时级别来暂停当前线程。你可以看到这比Thread的sleep方法的可读的好多了。记住TimeUnit.sleep()内部调用的Thread.sleep()也会抛出InterruptException。你也可以查看JDK源代码去验证一下。下面是一个简单例子,它展示如果使用TimeUnit.sleep()方法。

public class TimeUnitTest {
 
    public static void main(String args[]) throws InterruptedException {
 
        System.out.println("Sleeping for 4 minutes using Thread.sleep()");
        Thread.sleep(4 * 60 * 1000);
        System.out.println("Sleeping for 4 minutes using TimeUnit sleep()");
 
        TimeUnit.SECONDS.sleep(4);
        TimeUnit.MINUTES.sleep(4);
        TimeUnit.HOURS.sleep(1);
        TimeUnit.DAYS.sleep(1);
    }
}

  除了sleep的功能外,TimeUnit还提供了便捷方法用于把时间转换成不同单位,例如,如果你想把秒转换成毫秒,你可以使用下面代码:

TimeUnit.SECONDS.toMillis(44)  // 返回44,000

TimeUnit vs Thread.sleep()

  目前我们讨论使用TimeUnit的好处是提高了可读性,但是有时候觉得其他方法更好,因为Thread.sleep()伴随java很早就出现了,几乎所有程序员都知道Thread.sleep(),都知道是将当前线程暂停,而对TimeUnit并不太熟悉。两个原因:一是对比起Thread.sleep(),TimeUnit不是很常用,第二是在它不在Thread类中,就像wait和notify同样不是在Thread中,反正这些需要一段时间才能被采用,并成为一个标准的方式。

  总结来说在你想用Thread.sleep()方法的地方你最好使用TimeUnit.sleep()方法来代替。它不仅可以提高代码的可读性而且能更加熟悉java.util.concurrent包,因为TimeUnit在并发编程中也是一个关键API。

 

出处: https://www.cnblogs.com/zhaoyanjun/p/5486726.html

    http://www.importnew.com/7219.html

转载于:https://www.cnblogs.com/myseries/p/10894006.html

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个使用java.util.concurrent.ThreadPoolExecutor测试的例子: ```java import java.util.concurrent.*; public class TestThreadPoolExecutor { public static void main(String[] args) { int corePoolSize = 2; int maxPoolSize = 4; long keepAliveTime = 10; TimeUnit unit = TimeUnit.SECONDS; BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<>(2); ThreadPoolExecutor executor = new ThreadPoolExecutor(corePoolSize, maxPoolSize, keepAliveTime, unit, workQueue); executor.execute(new Task("任务1")); executor.execute(new Task("任务2")); executor.execute(new Task("任务3")); executor.execute(new Task("任务4")); executor.execute(new Task("任务5")); executor.shutdown(); } static class Task implements Runnable { private String name; public Task(String name) { this.name = name; } @Override public void run() { System.out.println(Thread.currentThread().getName() + " 正在执行 " + name); try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + " 执行 " + name + " 完成"); } } } ``` 输出结果: ``` pool-1-thread-1 正在执行 任务1 pool-1-thread-2 正在执行 任务2 pool-1-thread-1 执行 任务1 完成 pool-1-thread-2 执行 任务2 完成 pool-1-thread-3 正在执行 任务3 pool-1-thread-4 正在执行 任务4 pool-1-thread-3 执行 任务3 完成 pool-1-thread-4 执行 任务4 完成 Exception in thread "main" java.util.concurrent.RejectedExecutionException: Task TestThreadPoolExecutor$Task@7f31245a rejected from java.util.concurrent.ThreadPoolExecutor@6d6f6e28[Running, pool size = 4, active threads = 4, queued tasks = 2, completed tasks = 0] at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:2063) at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:830) at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1379) at TestThreadPoolExecutor.main(TestThreadPoolExecutor.java:16) ``` 在这个例子中,我们创建了一个ThreadPoolExecutor对象,并向其中添加了5个任务。由于线程池的核心线程数为2,最大线程数为4,所以前两个任务会立即执行,而后面的三个任务会被放入阻塞队列中等待执行。由于阻塞队列的大小为2,所以当第5个任务被添加时,阻塞队列已满,此时线程池会创建新的线程来执行任务。由于线程池的最大线程数为4,所以当第6个任务被添加时,线程池已经达到最大线程数,此时会抛出RejectedExecutionException异常。最后,我们调用了线程池的shutdown()方法来关闭线程池。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值