zoukankan      html  css  js  c++  java
  • java 多线程,线程安全等定义

    线程安全,

    synchronized的使用,保证方法或代码块操作的原子性、可见性和有序性

    参考这篇文章:

    7张图带你轻松理解Java 线程安全

    public class ThreadDemo {
        private int x = 0;
    
        //这个加了线程锁的方法,下面的runTest()方法内部有两个线程在调用当时,保证了count()的调用只能在
        //同一时间被一个线程访问,保证了成员变量x(共享内存里的同一个变量)的原子性,即保证同一时间只能一个线程对x进行调用,并同步到共享内存中。
        //如果去掉线程锁(synchronized),则会出现两个输出没有一个值是2000000,这就是因为没线程锁,导致x被同时访问,不能完成写入,又被其他线程调用,同步进去的值就会出错。
        private synchronized void count() {
            x++;
        }
    
        public void runTest() {
            new Thread() {
                @Override
                public void run() {
                    for (int i = 0; i < 1_000_000; i++) {
                        count();
                    }
                    System.out.println("final x from 1: " + x);
                }
            }.start();
            new Thread() {
                @Override
                public void run() {
                    for (int i = 0; i < 1_000_000; i++) {
                        count();
                    }
                    System.out.println("final x from 2: " + x);
                }
            }.start();
        }
    
        public static void main(String[] args) {
            new ThreadDemo().runTest();
        }
    }
    

      

    个方法主动加锁(Lock)的方式,也能保证成员变量的线程安全,例子如下:

    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReentrantReadWriteLock;
    
    public class threaDemo2 {
    	ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
    	Lock readLock = lock.readLock();
    	Lock writeLock = lock.writeLock();
    	private int x = 0;
    	private void count() {
    	    writeLock.lock();
    	    try {
    	        x++;
    	    } finally {
    	        writeLock.unlock();
    	    }
    	}
    	private void print(int time) {
    	    readLock.lock();
    	    try {
    	        for (int i = 0; i < time; i++) {
    	            System.out.print(x + " ");
    	        }
    	        System.out.println();
    	    } finally {
    	        readLock.unlock();
    	    }
    	}
    	public void operation(){
    		new Thread(){
    			public void run() {
    				for (int i=0;i<1000000;i++)
    				count();
    				System.out.println("sum1:"+x);
    			} 
    				
    			}.start();
    			
    			new Thread(){
    				public void run() {
    					for (int i=0;i<1000000;i++)
    					count();
    					System.out.println("sum2:"+x);
    					} 					
    				}.start();
    			
    	}
    	
    	
    	public static void main(String[] args) {
    	
    		new threaDemo2().operation();
    	}
    
    }
    

      

  • 相关阅读:
    linux内存的使用与page buffer (转)
    基于linux2.6.38.8内核的SDIO/wifi驱动分析(转)
    RamDisk块设备驱动实例开发讲解一
    Linux加密框架设计与实现(转)
    v4l2子系统学习心得
    一句memset引发的疑案
    linux 信号量之SIGNAL 0(转)
    可重入函数
    从ARM VIVT看linux的cache 处理
    内核抢占与preempt_count
  • 原文地址:https://www.cnblogs.com/zz22--/p/11224131.html
Copyright © 2011-2022 走看看