Java-----JUC

一、JUC概述

          在java5.0之后推出了java.util.concurrent(简称JUC)包,在此包中提供了很多在并发编程中使用的工具类,用于定义类似于

线程的自定义子系统,包括线程池,异步IO和轻量级任务框架,还提供了用于多线程上下文中的 Collection实现等。

并发编程中有三个特性:

                         原子性(互斥性) :  代码不可拆封,i++ 就不是原子操作,它可以拆分为三个步骤 temp1=i;

                                                                                                                                                            temp2=temp1+1;

                                                                                                                                                            i=temp2;

                         指令重排序:虚拟机在编译程序时,为了优化,可能不会按照你所写的代码循序执行

                         内存可见性:在多线程同时访问一个临界资源,当一个线程改变临界资源值的时候,其它线程要知道!

二、volatile

                          volatile 关键字: 当多个线程进行操作共享数据时,可以保证内存中的数据是可见的;相较于 synchronized 是一种

                                                   较为轻量级的同步策略;

                          volatile 不具备互斥性。

                          synchronizedvolatile的区别

                             synchronized可以保证原子性,内存可见性,但不能保证指令重排序。

                             voliatle可以保证内存可见性,禁止指令重排序,但不能保证原子性

public class MyThread implements Runnable{
    /* int  n=0;
    @Override
    public void run() {
        while (true){
            synchronized (this) {
                if(n>=10) {
                    break;
                }
                try {
                    Thread.sleep(200);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(n++);
            }
        }
    }*/

//下面使用的是原子变量操作  和上面n++效果相同
    private AtomicInteger ai = new AtomicInteger(0);  /创建这个类对象 初始值为1
    @Override
    public void run() {
        System.out.println(ai.getAndIncrement());//getAndIncrement()自增1
    }
}
//测试类
public class MyThreadTest{
    public static void main(String[] args) {
        MyThread myThread = new MyThread();
        for (int i=0;i<10;i++) {
            new Thread(myThread).start();
        }

    }
}

三、CAS算法

          是硬件对并发的支持,针对多处理器操作而设计的处理处理器中的一种操作指令,用于管理对共享数据的并发访问。

          CAS是一种无锁的非阻塞算法(乐观锁)的实现。   阻塞(同一时刻,只允许一个线程访问临界资源,加锁

                CAS 包含了三个操作数:

                              进行比较的旧预估值: A

                              需要读写的内存值: V

                              将写入的更新值: B

                              当且仅当 A == V 时, V = B, 否则,将不做任何操作,并且这个比较交换过程属于原子操作;

//模拟CAS算法
public class CompareAndSwapDemo {
	public static void main(String[] args) {
		CompareAndSwap compareAndSwap = new CompareAndSwap();
		for (int i = 0; i < 10; i++) {
			new Thread(new Runnable() {
				@Override
				public void run() {

					int expect = compareAndSwap.get();
					boolean b = compareAndSwap.compareAndSwap(expect, new Random().nextInt(101));
					System.out.println(b);
				}
			}).start();
		}
	}
}

class CompareAndSwap {
	private int value;

	/**
	 * 获取值
	 * 
	 * @return
	 */
	public synchronized int get() {
		return value;
	}

	public synchronized boolean compareAndSwap(int expect, int newValue) {
		if (this.value == expect) {
			this.value = newValue;
			return true;
		}
		return false;
	}
}

 

在CAS算法中,需要取出内存中某时刻的数据(由用户完成),在下一时刻比较并替换(由CPU完成,该操作是原子的)。这个时间差中,会导致数据的变化。
假设如下事件序列:
线程 1 从内存位置V中取出A。
线程 2 从位置V中取出A。
线程 2 进行了一些操作,将B写入位置V。
线程 2 将A再次写入位置V。
线程 1 进行CAS操作,发现位置V中仍然是A,操作成功。

尽管线程 1 的CAS操作成功,但不代表这个过程没有问题——对于线程 1 ,线程 2 的修改已经丢失。

CAS算法会出现ABA问题,为了解决这个问题可以增加版本号,记录更改次数(AtomicStampedReference)

//使用AtomicStampedReference解决ABA问题
public static void main(String[] args) {
        AtomicStampedReference asr = new AtomicStampedReference(1, 1);
        for (int i = 0; i < 50; i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    Object old = asr.getReference();  //获取旧值
                    int oldStamp = asr.getStamp();//获取版本号
                                                // 旧值     新值                   老的标记    新标记
                    boolean b = asr.compareAndSet(old,new Random().nextInt(1000), oldStamp,oldStamp+1);
                    System.out.println(b);
                }
            }).start();

        }
    }

 

你可能感兴趣的:(Java-----JUC)