• Java 多线程序的一点理解


    synchronized 是java 内主要的同步标记

    1 同步非静态方法

      作用域范围只是当前对象在不同线程间的同步, 如果n 为Test外的对象,在不同的Test对象之间,等于没有同步, 该方法只能同步n为Test类内对象

           

    public class Test	
    public  synchronized void inc() {
    			n++;
    		}
    }
    

      如果想同步类外的n,使用同步代码块对象,对象也为一个类外对象,相对所有Test对象来说, 也只有一个,所以就能同步

    final Integer lock = new Integer(1);
    	class Test  implements Runnable {
    		public int value = 0;
    		public  void inc() {
    			synchronized (lock) 
    			{
    				m++;
    				value++;
    				n++;
    			}
    		}
    

      

    2  同步静态方法

      

    public class Test	
    public  static synchronized void inc() {
    			n++;
    		}
    }
    

      作用域范围是所有Test类对象,  inc方法在所有Test对象之间只能被一个同时调用

    3  同步代码块 

    publci class Test{
         public  void inc() {
    			synchronized (lock) 
    			{
    				// m++;
    				value++;
    				n++;
    			}
    		}
    }
    

      

      作用域范围,取决于lock的相对该类的作用域范围

    如果lock 是该类以外的对象,相对所有的Test 对象而言,  lock是个全局变量,  synchronized同步范围在所有对象之间

    如果lock 是该类以内的对象,如类内变量,相对所有的Test 对象而言,  lock是个本地局部变量,  synchronized同步范围在同一对象的不同线程之间, 和同步非静态方法一样

    测试代码

    import java.util.concurrent.CountDownLatch;
    import java.util.concurrent.CountDownLatch;
    
    public class TestVolatile {
    	public static volatile int  n = 0; // 
    	public  Integer m = 0;
    	final Integer lock = new Integer(1);
    
    	class MyThread implements Runnable {
    		public int value = 0;
    		public  void inc() {
    			synchronized (lock) 
    			{
    				m++;
    				value++;
    				n++;
    			}
    		}
    
    		public void run() {
    
    			{
    				for (int i = 0; i < 1000; i++)
    					try {
    						// System.out.println(i);
    						inc();
    						// m++;
    						// vboolean = vboolean == true ? false : true;
    						Thread.sleep(3); // 为了使运行结果更随机,延迟3毫秒
    					} catch (Exception e) {
    					}
    			}
    		}
    	}
    
    	static class MyThread1 implements Runnable {
    		public static Integer locallock = new Integer(2);
    		public static synchronized void inc() {
    			n++;
    		}
    
    		public  void run() {
    			for (int i = 0; i < 1000; i++)
    				try {
    					//inc();  方法一
    					
    					// 方法二 
    					synchronized (locallock){ 
    					    n = n + 1;
    				}
    					Thread.sleep(3);
    				} catch (Exception e) {
    				}
    		}
    	}
    
    	class MyThread2 implements Runnable {
    		public void run() {
    			synchronized (lock) {
    				for (int i = 0; i < 100; i++)
    					try {
    						m++;
    						Thread.sleep(3); // 为了使运行结果更随机,延迟3毫秒
    					} catch (Exception e) {
    					}
    			}
    		}
    	}
        
    	// 3和2代码一样,只是一个是分开锁, 一个只是单独加锁, 效率相差10倍左右。
    	class MyThread3 implements Runnable {
    		public void inc() {
    			synchronized (lock) {
    				m++;
    			}
    		}
    
    		public void run() {
    			for (int i = 0; i < 1000; i++)
    				try {
    					inc();
    					Thread.sleep(3); // 为了使运行结果更随机,延迟3毫秒
    				} catch (Exception e) {
    				}
    		}
    	}
    	
    	public Value g_value = new Value();
    	public class Value{
    		public synchronized void inc() 
    		{
    			m++;
    		}
    	}
        
    	// 4和3功能差不多,只是 MyThread4, 使用全局变量g_value 的锁,不同线程间同步
    	class MyThread4 implements Runnable {
    		public int value = 0;
    		public  void inc() {
    			{
    				g_value.inc();
    			}
    		}
    
    		public void run() {
    				for (int i = 0; i < 1000; i++)
    					try {
    						inc();
    						Thread.sleep(3); // 为了使运行结果更随机,延迟3毫秒
    					} catch (Exception e) {
    					}
    			}
    	}
    
    	public void runthread() throws InterruptedException {
    		long beg = System.currentTimeMillis();
    		MyThread1[] mythreadary = new MyThread1[100];
    		Thread[] threadary = new Thread[100];
    		for (int i = 0; i < threadary.length; i++) {
    			mythreadary[i] = new MyThread1();
    			threadary[i] = new Thread(mythreadary[i], "test1");
    		}
    
    		for (int i = 0; i < threadary.length; i++) {
    			threadary[i].start();
    		}
    
    		for (int i = 0; i < threadary.length; i++) {
    			threadary[i].join();
    		   // System.out.println((mythreadary[i]).value);
    		}
    
    		System.out.println(TestVolatile.n);
    		System.out.println(m);
    
    		System.out.println("程序耗时: " + (System.currentTimeMillis() - beg));
    	}
    
    	public static void main(String[] args) throws InterruptedException {
    		TestVolatile tmp = new TestVolatile();
    		tmp.runthread();
    	}
    }
    

      

  • 相关阅读:
    MongoDB 集合上限说明
    MongoDB mtools-你可能没用过的mongodb神器(转载)
    Redis 你知道 Redis 的字符串是怎么实现的吗?(转载)
    Mongoimport 导数据自动去重
    MongoDB 数据类型
    MongoDB 数据类型整理
    MongoDB mongoimport 时间格式处理
    MongoDB 空值数组查询
    MongoDB WiredTiger 存储引擎cache_pool设计(转载)
    MongoDB运维实战lsm降低Disk Lantency(转载)
  • 原文地址:https://www.cnblogs.com/chengxin1982/p/4010407.html
Copyright © 2020-2023  润新知