大战熟女丰满人妻av-荡女精品导航-岛国aaaa级午夜福利片-岛国av动作片在线观看-岛国av无码免费无禁网站-岛国大片激情做爰视频

Java多線程編程概述
Java多線程的安全問題
Java多線程同步
Java多線程間的通信
Java線程Lock
Java多線程管理
保障線程安全的設計技術
Java鎖的優化及注意事項
Java多線程集合
【Java多線程】單例模式與多線程

Java原子變量

原子變量類基于CAS實現的, 當對共享變量進行read-modify-write更新操作時,通過原子變量類可以保障操作的原子性與可見性.對變量的read-modify-write更新操作是指當前操作不是一個簡單的賦值,而是變量的新值依賴變量的舊值,如自增操作i++. 由于volatile只能保證可見性,無法保障原子性, 原子變量類內部就是借助一個Volatile變量,并且保障了該變量的read-modify-write操作的原子性, 有時把原子變量類看作增強的volatile變量. 原子變量類有12個,如:

               分組              原子變量類
基礎數據型 AtomicInteger, AtomicLong, AtomicBoolean
數組型 AtomicIntegerArray, AtomicLongArray,AtomicReferenceArray
字段更新器 AtomicIntegerFieldUpdater, AtomicLongFieldUpdater, AtomicReferenceFieldUpdater
引用型 AtomicReference,AtomicStampedReference, AtomicMarkableReference

AtomicLong 

package com.wkcto.atomics.atomiclong;

import java.util.concurrent.atomic.AtomicLong;

/**
 * 使用原子變量類定義一個計數器
 * 該計數器,在整個程序中都能使用,并且所有的地方都使用這一個計數器,這個計數器可以設計為單例
 * 北京動力節點老崔
 */
public class Indicator {
    //構造方法私有化
    private  Indicator(){}
    //定義一個私有的本類靜態的對象
    private static  final  Indicator INSTANCE = new Indicator();
    //3)提供一個公共靜態方法返回該類唯一實例
    public static  Indicator getInstance(){
        return INSTANCE;
    }

    //使用原子變量類保存請求總數,成功數,失敗數
    private final AtomicLong requestCount = new AtomicLong(0);  //記錄請求總數
    private final AtomicLong successCount = new AtomicLong(0);  //處理成功總數
    private final AtomicLong fialureCount = new AtomicLong(0);  //處理失敗總數

    //有新的請求
    public void newRequestReceive(){
        requestCount.incrementAndGet();
    }
    //處理成功
    public void requestProcessSuccess(){
        successCount.incrementAndGet();
    }
    //處理失敗
    public void  requestProcessFailure(){
        fialureCount.incrementAndGet();
    }

    //查看總數,成功數,失敗數
    public long getRequestCount(){
        return requestCount.get();
    }
    public long getSuccessCount(){
        return successCount.get();
    }
    public long getFailureCount(){
        return fialureCount.get();
    }
}
package com.wkcto.atomics.atomiclong;

import java.util.Random;

/**
 * 模擬服務器的請求總數, 處理成功數,處理失敗數
 * 北京動力節點老崔
 */
public class Test {
    public static void main(String[] args) {
        //通過線程模擬請求,在實際應用中可以在ServletFilter中調用Indicator計數器的相關方法
        for (int i = 0; i < 10000; i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    //每個線程就是一個請求,請求總數要加1
                    Indicator.getInstance().newRequestReceive();
                    int num = new Random().nextInt();
                    if ( num % 2 == 0 ){        //偶數模擬成功
                        Indicator.getInstance().requestProcessSuccess();
                    }else {     //處理失敗
                        Indicator.getInstance().requestProcessFailure();
                    }
                }
            }).start();
        }

        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        //打印結果
        System.out.println( Indicator.getInstance().getRequestCount());     //總的請求數
        System.out.println( Indicator.getInstance().getSuccessCount());     //成功數
        System.out.println( Indicator.getInstance().getFailureCount());     //失敗數
    }
}

AtomicIntegerArray

原子更新數組

package com.wkcto.atomics.atomicarray;

import java.util.concurrent.atomic.AtomicIntegerArray;

/**
 * AtomicIntegerArray的基本操作
 * 原子更新數組
 * 北京動力節點老崔
 */
public class Test {
    public static void main(String[] args) {
        //1)創建一個指定長度的原子數組
        AtomicIntegerArray atomicIntegerArray = new AtomicIntegerArray(10);
        System.out.println( atomicIntegerArray );   //[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
        //2)返回指定位置的元素
        System.out.println( atomicIntegerArray.get(0));     //0
        System.out.println( atomicIntegerArray.get(1));     //0
        //3)設置指定位置的元素
        atomicIntegerArray.set(0, 10);
        //在設置數組元素的新值時, 同時返回數組元素的舊值
        System.out.println( atomicIntegerArray.getAndSet(1, 11) );  //0
        System.out.println( atomicIntegerArray );   //[10, 11, 0, 0, 0, 0, 0, 0, 0, 0]
        //4)修改數組元素的值,把數組元素加上某個值
        System.out.println( atomicIntegerArray.addAndGet(0, 22) );  //32
        System.out.println( atomicIntegerArray.getAndAdd(1, 33));   //11
        System.out.println( atomicIntegerArray );   //[32, 44, 0, 0, 0, 0, 0, 0, 0, 0]
        //5)CAS操作
        //如果數組中索引值為0的元素的值是32 , 就修改為222
        System.out.println( atomicIntegerArray.compareAndSet(0, 32, 222));  //true
        System.out.println( atomicIntegerArray );   //[222, 44, 0, 0, 0, 0, 0, 0, 0, 0]
        System.out.println( atomicIntegerArray.compareAndSet(1, 11, 333));  //false
        System.out.println(atomicIntegerArray);
        //6)自增/自減
        System.out.println( atomicIntegerArray.incrementAndGet(0) );    //223, 相當于前綴
        System.out.println( atomicIntegerArray.getAndIncrement(1));     //44, 相當于后綴
        System.out.println( atomicIntegerArray );   //[223, 45, 0, 0, 0, 0, 0, 0, 0, 0]
        System.out.println( atomicIntegerArray.decrementAndGet(2));     //-1
        System.out.println( atomicIntegerArray);    //[223, 45, -1, 0, 0, 0, 0, 0, 0, 0]
        System.out.println( atomicIntegerArray.getAndDecrement(3));     //0
        System.out.println( atomicIntegerArray );   //[223, 45, -1, -1, 0, 0, 0, 0, 0, 0]
    }
}
package com.wkcto.atomics.atomicarray;

import java.util.concurrent.atomic.AtomicIntegerArray;

/**
 * 在多線程中使用AtomicIntegerArray原子數組
 * 北京動力節點老崔
 */
public class Test02 {
    //定義原子數組
    static AtomicIntegerArray atomicIntegerArray = new AtomicIntegerArray(10);

    public static void main(String[] args) {
        //定義線程數組
        Thread[] threads = new Thread[10];
        //給線程數組元素賦值
        for (int i = 0; i < threads.length; i++) {
            threads[i] = new AddThread();
        }
        //開啟子線程
        for (Thread thread : threads) {
            thread.start();
        }
        //在主線程中查看自增完以后原子數組中的各個元素的值,在主線程中需要在所有子線程都執行完后再查看
        //把所有的子線程合并到當前主線程中
        for (Thread thread : threads) {
            try {
                thread.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println( atomicIntegerArray );
    }

    //定義一個線程類,在線程類中修改原子數組
    static class AddThread extends Thread{
        @Override
        public void run() {
            //把原子數組的每個元素自增1000次
            for (int j = 0; j < 100000; j++) {
                for (int i = 0; i < atomicIntegerArray.length(); i++) {
                    atomicIntegerArray.getAndIncrement(i % atomicIntegerArray.length());
                }
            }
           /* for (int i = 0; i < 10000; i++) {
                atomicIntegerArray.getAndIncrement(i % atomicIntegerArray.length());
            }*/
        }
    }
}

AtomicIntegerFieldUpdater

AtomicIntegerFieldUpdater可以對原子整數字段進行更新,要求:
● 字符必須使用volatile修飾,使線程之間可見。
● 只能是實例變量,不能是靜態變量,也不能使用final修飾。

package com.wkcto.atomics.atominintegerfiled;

/**
 * 使用AtomicIntegerFieldUpdater更新的字段必須使用volatile修飾
 * 北京動力節點老崔
 */
public class User {
    int id;
    volatile  int age;

    public User(int id, int age) {
        this.id = id;
        this.age = age;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", age=" + age +
                '}';
    }
}
package com.wkcto.atomics.atominintegerfiled;

import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;

/**
 * 線程類,
 * 北京動力節點老崔
 */
public class SubThread extends Thread {
    private  User user;         //要更新的User對象
    //創建AtomicIntegerFieldUpdater更新器
    private AtomicIntegerFieldUpdater<User> updater = AtomicIntegerFieldUpdater.newUpdater(User.class, "age");

    public SubThread(User user) {
        this.user = user;
    }

    @Override
    public void run() {
        //在子線程中對user對象的age字段自增10次
        for (int i = 0; i < 10; i++) {
            System.out.println( updater.getAndIncrement(user));
        }
    }
}
package com.wkcto.atomics.atominintegerfiled;

/**
 * 北京動力節點老崔
 */
public class Test {
    public static void main(String[] args) {
        User user = new User(1234, 10);
        //開啟10個線程
        for (int i = 0; i < 10; i++) {
            new SubThread(user).start();
        }

        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println( user );
    }
}

AtomicReference

可以原子讀寫一個對象

package com.wkcto.atomics.atomicreference;

import java.util.Random;
import java.util.concurrent.atomic.AtomicReference;

/**
 * 使用AtomicReference原子讀寫一個對象
 * 北京動力節點老崔
 */
public class Test01 {
    //創建一個AtomicReference對象
    static AtomicReference<String> atomicReference = new AtomicReference<>("abc");

    public static void main(String[] args) throws InterruptedException {
        //創建100個線程修改字符串
        for (int i = 0; i < 100; i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        Thread.sleep(new Random().nextInt(20));
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    if (atomicReference.compareAndSet("abc","def")){
                        System.out.println(Thread.currentThread().getName() + "把字符串abc更改為def");
                    }
                }
            }).start();
        }
        //再創建100個線程
        for (int i = 0; i < 100; i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        Thread.sleep(new Random().nextInt(20));
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    if (atomicReference.compareAndSet("def","abc")){
                        System.out.println(Thread.currentThread().getName() + "把字符串還原為abc");
                    }
                }
            }).start();
        }

        Thread.sleep(1000);
        System.out.println(atomicReference.get());
    }
}
package com.wkcto.atomics.atomicreference;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;

/**
 * 演示AtomicReference可能會出現CAS的ABA問題
 * 北京動力節點老崔
 */
public class Test02 {
    private static AtomicReference<String> atomicReference = new AtomicReference<>("abc");
    public static void main(String[] args) throws InterruptedException {
        //創建第一個線程,先把abc字符串改為"def",再把字符串還原為abc
        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                atomicReference.compareAndSet("abc", "def");
                System.out.println(Thread.currentThread().getName() + "--" + atomicReference.get());
                atomicReference.compareAndSet("def", "abc");
            }
        });

        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    TimeUnit.SECONDS.sleep(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println( atomicReference.compareAndSet("abc", "ghg"));
            }
        });
        t1.start();
        t2.start();
        t1.join();
        t2.join();
        System.out.println( atomicReference.get());
    }
}
package com.wkcto.atomics.atomicreference;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.atomic.AtomicStampedReference;

/**
 * AtomicStampedReference原子類可以解決CAS中的ABA問題
 * 在AtomicStampedReference原子類中有一個整數標記值stamp, 每次執行CAS操作時,需要對比它的版本,即比較stamp的值
 * 北京動力節點老崔
 */
public class Test03 {
//    private static AtomicReference<String> atomicReference = new AtomicReference<>("abc");
    //定義AtomicStampedReference引用操作"abc"字符串,指定初始化版本號為0
    private static AtomicStampedReference<String> stampedReference = new AtomicStampedReference<>("abc", 0);
    public static void main(String[] args) throws InterruptedException {
        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                stampedReference.compareAndSet("abc", "def", stampedReference.getStamp(), stampedReference.getStamp()+1);
                System.out.println(Thread.currentThread().getName() + "--" +stampedReference.getReference());
                stampedReference.compareAndSet("def", "abc", stampedReference.getStamp(), stampedReference.getStamp()+1);
            }
        });
        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                int stamp = stampedReference.getStamp();        //獲得版本號
                try {
                    TimeUnit.SECONDS.sleep(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println( stampedReference.compareAndSet("abc", "ggg", stamp, stamp+1));
            }
        });

        t1.start();
        t2.start();
        t1.join();
        t2.join();

        System.out.println( stampedReference.getReference() );
    }
}

 

全部教程
主站蜘蛛池模板: 成人在线观看不卡 | 欧美精品亚洲精品日韩 | avtom影院入口四虎 | 色涩网站在线观看 | 久久亚洲精品永久网站 | 奇米影视777888 | 成年女人免费视频 | 四虎影视永久免费视频观看 | 综合国产 | 日韩精品综合 | 婷婷色基地 | 久久国产精品亚洲va麻豆 | 超级毛片| 欧美理伦| 中国一级特黄aa毛片大片 | 午夜噜噜噜私人影院在线播放 | 国产一级特黄全黄毛片 | 精品一久久香蕉国产线看播放 | 精品一区二区久久久久久久网精 | 欧美精品一区二区三区久久 | 午夜精品福利影院 | 久久久日韩精品国产成人 | 久久99精品这里精品动漫6 | 国产乱子伦手机在线 | 亚洲va高清中文字幕 | 欧美性生活视频免费 | 国产动作大片中文字幕 | 日本色图在线 | 一级毛片观看 | 亚洲国产成人久久精品影视 | 精品精品国产高清a毛片牛牛 | 久久精品九九 | 久久伊人最新 | 在线免费福利 | 国产精品综合网 | 丁香六月色婷婷 | 国内自拍tv在线 | 波多野结衣一区二区 三区 波多野结衣一区二区三区 波多野结衣一区二区三区高清在线 | 成年女人黄小视频 | 久久精品夜色国产 | 国产一区二区三区久久精品小说 |