美文网首页
多线程(17) — Atomic并发包及Timer定时器

多线程(17) — Atomic并发包及Timer定时器

作者: 烧杰 | 来源:发表于2018-04-17 22:24 被阅读0次

    Atomic并发包

    java.util.concurrent.atomic包:在多线程环境下可以对基本数据进行原子操作,无锁的进行原子操作在Atomic包里的类基本都是使用Unsafe实现的包装类。Atomic原子类在多个线程一起执行的时候,不会被其他线程干扰。

    (Atomic包里的类基本都是使用Unsafe实现的,看Unsafe源码,发现Unsafe提供了三种CAS方法,compareAndSwapObject,compareAndSwapInt和compareAndSwapLong,而CAS的源码则是native底层的。再看AtomicBoolean源码,发现其是先把Boolean转换成整型,再使用compareAndSwapInt进行CAS,所以原子更新double也可以用类似的思路来实现。)

    CAS指:一个线程间共享的变量,首先在主存中会保留一份,然后每个线程的工作内存也会保留一份副本。这里说的预期值,就是线程保留的副本。当该线程从主存中获取该变量的值后,主存中该变量可能已经被其他线程刷新了,但是该线程工作内存中该变量却还是原来的值,这就是所谓的预期值了。当你要用CAS刷新该值的时候,如果发现线程工作内存和主存中不一致了,就会失败,如果一致,就可以更新成功。

    AtomicInteger部分源码:

    public final int getAndSet(int newValue) {
            for (;;) {
                int current = get();
                if (compareAndSet(current, newValue))
                    return current;
            }
        }
    

    由上AtomicInteger的getAndSet源码可以发现,当CAS发现值相同,说明线程中的数据并没有被影响直接返回current值,若不一样就为false,则线程会一直阻塞。(也可以通过CAS的这个方法去检验线程是否受到干扰)

    ===================

    Timer 定时器

    通过Timer类下调用schedule进行定时调度任务:

      public static void main(String[] args) {
            new Timer().schedule(new TimerTask() {
                @Override
                public void run() {
                    System.out.println("Time..Ending...");
                }
            }, 5000,2000);
    

    程序会隔5s打印,以后每隔2s周期再打印。


    image.png

    问:即然2000代表每隔一个周期调用,那可以设计一个变周期的吗,比如开始5s到计时一次,再1s倒计时,再2s倒计时,3s...这样下去?

    答:设计两个计时器,用 i 计加数来完成:


    image.png
    image.png

    有几个点需要注意:1.i注意要全局变量,而且内部类不能有静态方法,所以提到全局的,由于main是static静态的所以也要加上static。2.匿名内部类只能使用一次,因为是匿名找不到名字的类,所以是一次性的。

    由此完成加一周期的Timer定时任务。

    相关文章

      网友评论

          本文标题:多线程(17) — Atomic并发包及Timer定时器

          本文链接:https://www.haomeiwen.com/subject/iagycftx.html