JAVA原子性与可见性(一)

1.可见性,是指线程之间的可见性,一个线程修改的状态对另一个线程是可见的。
也就是一个线程修改的结果。另一个线程马上就能看到。比如:用volatile修饰的变量,就会具有可见性。
2.原子性,原子是世界上的最小单位,具有不可分割性。比如 int a=0,a=a+1不是原子性操作。
(1).非原子操作都会存在线程安全问题,需要我们使用同步技术(sychronized)来让它变成一个原子操作。
(2).java的concurrent包下提供了一些原子类,我们可以通过阅读API来了解这些原子类的用法。
比如:AtomicInteger、AtomicLong、AtomicReference等。
(3).使用ReentrantLock,实现原子性
(1)(2)(3)测试例如下:
package userWeb;


import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
 * 
 * @author 并发操作,原子性测试类
 *
 */
public class AtomicIntegerTest {
private static Integer sycNumber=0;
private static Integer lockNumber=0;
public static AtomicInteger atomicNumber = new AtomicInteger(0);
public static Lock lock =  new ReentrantLock();
   
public synchronized static void increaseSyn(){
try {
Thread.sleep(300);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
sycNumber++;


}
public static void increaseLock(){
try {
Thread.sleep(300);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}


lock.lock();


try{
lockNumber++;//这块的代码实际项目中可能会出现异常,所以要捕获
}finally{
lock.unlock();//用try finally块保证Unlock一定要执行
}




}
    public static void increaseAtomic(){
       try {
           Thread.sleep(300);
       } catch (InterruptedException e) {
           // TODO Auto-generated catch block
           e.printStackTrace();
       }
      
       atomicNumber.getAndIncrement();//获得当前值并且加1
   }
//注意:  主线程 与另外1000线程工作相互不影响,存在一个问题,当主线程运行完时,其他1000个线程未结束,打印出结果不是预想的结果 
    //while(Thread.activeCount() > 1) 判断当前线程的线程组中活动线程的数目
public static void main(String[] args) {
//同时启动1000个线程,去进行i++计算,看看实际结果 
        for (int i = 0; i < 1000; i++) {
new Thread(new Runnable() {
@Override
public void run() {
AtomicIntegerTest.increaseLock();
AtomicIntegerTest.increaseSyn();
AtomicIntegerTest.increaseAtomic();
}
}).start();
}
        while(Thread.activeCount() > 1){
        Thread.yield();//还有子线程运行,主线程让出cpu,等待子线程执行完  
        //sleep()可以使低优先级的线程得到执行的机会,当然也可以让同优先级、高优先级的线程有执行的机会。
        //yield与sleep()类似,只是不能由用户指定暂停多长时间,并且yield()方法只能让同优先级的线程有执行的机会。
        }
System.out.println(sycNumber);
System.out.println(lockNumber);
System.out.println(atomicNumber);
}
}

你可能感兴趣的:(JAVA原子性与可见性(一))