多线程实现数据共享

Java支持多个线程同时访问一个对象或者对象的成员变量,

使用关键字synchronized可以保证了线程对共享变量访问的可见性和排他性

使用cas机制可以控制线程对共享变量写操作的原子性。

一,使用共享对象和synchronized实现数据共享

   public static void main(String[] args) {
        // 共享的对象
        MyData myData = new MyData();
        // 创建5个线程 传入共享的对象
        for(int i = 0;i<5;i++) {
            new MyThread(myData).start();
        }
        SleepTools.second(5);
        System.out.println("main is ended!最终的值"+myData.getJ());
    }
    //具体操作线程 实现共享对的值+1
    private static class MyThread extends Thread{
        public MyData myData;
        public MyThread(MyData myData) {
            this.myData = myData;
        }
        @Override
        public void run() {
            try {
                //模拟其他业务操作 休眠一秒代替
                TimeUnit.SECONDS.sleep(1);
                //对共享的数据 +1 操作
                synchronized (myData){
                    addNumber();//值加一操作
                }
                //模拟其他业务操作 休眠一秒代替
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        public  void addNumber(){
            System.out.println(Thread.currentThread().getName()+"取值为 ......."+myData.getJ());
            myData.setJ(myData.getJ()+1);
            System.out.println(Thread.currentThread().getName()+"增加一后值......."+myData.getJ());
        }
    }

    // 共享的对象类
    public static class MyData {
        // 共享对象的属性
        private int j = 0;

        public int getJ() {
            return j;
        }
        public void setJ(int j) {
            this.j = j;
        }
    }

运行结果如下:

Thread-3取值为 .......0
Thread-3增加一后值.......1
Thread-0取值为 .......1
Thread-0增加一后值.......2
Thread-1取值为 .......2
Thread-1增加一后值.......3
Thread-2取值为 .......3
Thread-2增加一后值.......4
Thread-4取值为 .......4
Thread-4增加一后值.......5
main is ended!最终的值5

二,使用静态变量和CAS机制实现,本例直接使用原子操作AtomicInteger

    public static AtomicInteger j = new AtomicInteger(0);

    private static class MyRunnable implements Runnable{
        @Override
        public void run() {
            //模拟其他业务操作 休眠一秒代替
            SleepTools.second(1);
            //getAndIncrement 以原子方式将当前值加1,注意,这里返回的是自增前的值
            int andIncrement = j.getAndIncrement();
            System.out.println(Thread.currentThread().getName() + "取值......." + andIncrement);
        }
    }

    public static void main(String[] args) {
        for(int i = 0;i<5;i++) {
            new Thread(new MyRunnable()).start();
        }
        SleepTools.second(5);
        System.out.println("main is ended!"+j);
    }

运行结果:

Thread-0取值.......2
Thread-4取值.......1
Thread-2取值.......3
Thread-3取值.......0
Thread-1取值.......4
main is ended!5

你可能感兴趣的:(java)