zoukankan      html  css  js  c++  java
  • Java线程同步操作

    synchronized

    作用于对象实例:对给定对象加锁,进入同步代码前要获得给定对象的锁。

    作用于实例方法:相当于对当前实例加锁,进入同步代码前要获得当前实例的锁。

    作用于静态方法:相当于对当前类加锁,进入同步代码前要获得当前类的锁。

    使用

    给实例对象加锁

    public class AccountingSync implements Runnable {
    	static AccountingSync instance = new AccountingSync();
    	static int i = 0;
    
    	@Override
    	public void run() {
    		for (int k = 0; k < 10000; k++) {
    			synchronized (instance) {
    				i++;
    			}
    		}
    	}
    
    	@Test
    	public void testInteger() throws InterruptedException {
    		int count = 10;
    		Thread[] ts = new Thread[count];
    
    		for (int k = 0; k < count; k++) {
    			ts[k] = new Thread(instance);
    		}
    
    		// start
    		for (int k = 0; k < count; k++) {
    			ts[k].start();
    		}
    
    		// join
    		for (int k = 0; k < count; k++) {
    			ts[k].join();
    		}
    
    		System.out.println(i);
    	}
    }
    

    给类方法加锁

    public class AccountingSync2 implements Runnable {
    	static AccountingSync2 instance = new AccountingSync2();
    	static int i = 0;
    
    	public synchronized void increase() {
    		i++;
    	}
    
    	@Override
    	public void run() {
    		for (int k = 0; k < 10000; k++) {
    			increase();
    		}
    	}
    
    	@Test
    	public void testInteger() throws InterruptedException {
    		int count = 10;
    		Thread[] ts = new Thread[count];
    
    		for (int k = 0; k < count; k++) {
    			ts[k] = new Thread(instance);
    		}
    
    		// start
    		for (int k = 0; k < count; k++) {
    			ts[k].start();
    		}
    
    		// join
    		for (int k = 0; k < count; k++) {
    			ts[k].join();
    		}
    
    		System.out.println(i);
    	}
    }
    

    给类方法加锁的错误演示

    public class AccountingSyncBad implements Runnable {
    	static int i = 0;
    
    	public synchronized void increase() {
    		i++;
    	}
    
    	@Override
    	public void run() {
    		for (int k = 0; k < 10000; k++) {
    			increase();
    		}
    	}
    
    	@Test
    	public void testInteger() throws InterruptedException {
    		int count = 10;
    		Thread[] ts = new Thread[count];
    
    		for (int k = 0; k < count; k++) {
    			ts[k] = new Thread(new AccountingSyncBad());
    		}
    
    		// start
    		for (int k = 0; k < count; k++) {
    			ts[k].start();
    		}
    
    		// join
    		for (int k = 0; k < count; k++) {
    			ts[k].join();
    		}
    
    		System.out.println(i);
    	}
    }
    

    假设把给类实例加锁中的每个实例比作一个门,上面的测试方法中每个门都有锁但是10个门10把锁,每个线程进一个门。还是不能保证临界区资源i同时只一个线程访问

    fix

    @Test
    public void testIntegerFix() throws InterruptedException {
      int count = 10;
      AccountingSyncBad instance = new AccountingSyncBad();
      Thread[] ts = new Thread[count];
    
      for (int k = 0; k < count; k++) {
        ts[k] = new Thread(instance);
      }
    
      // start
      for (int k = 0; k < count; k++) {
        ts[k].start();
      }
    
      // join
      for (int k = 0; k < count; k++) {
        ts[k].join();
      }
    
      System.out.println(i);
    }
    

    给静态类方法加锁

    public class AccountingSyncClass implements Runnable {
    	static int i = 0;
    
    	public static synchronized void increase() {
    		i++;
    	}
    
    	@Override
    	public void run() {
    		for (int k = 0; k < 10000; k++) {
    			increase();
    		}
    	}
    
    	@Test
    	public void testInteger() throws InterruptedException {
    		int count = 10;
    		Thread[] ts = new Thread[count];
    
    		for (int k = 0; k < count; k++) {
    			ts[k] = new Thread(new AccountingSyncClass());
    		}
    
    		// start
    		for (int k = 0; k < count; k++) {
    			ts[k].start();
    		}
    
    		// join
    		for (int k = 0; k < count; k++) {
    			ts[k].join();
    		}
    
    		System.out.println(i);
    	}
    	
    	@Test
    	public void testIntegerFix() throws InterruptedException {
    		int count = 10;
    		AccountingSyncClass instance = new AccountingSyncClass();
    		Thread[] ts = new Thread[count];
    
    		for (int k = 0; k < count; k++) {
    			ts[k] = new Thread(instance);
    		}
    
    		// start
    		for (int k = 0; k < count; k++) {
    			ts[k].start();
    		}
    
    		// join
    		for (int k = 0; k < count; k++) {
    			ts[k].join();
    		}
    
    		System.out.println(i);
    	}
    }
    

    上面测试的testInteger方法和testIntegerFix方法都能得到正确的结果,原因是给静态类方法加锁相当于10个门用的同一把锁,保证了同一时间只有一个线程能访问临界区资源i。

  • 相关阅读:
    Metronic最优秀的基于Bootstrap的响应式网站模版
    SMINT:单页网站的免費jQuery插件
    不做全栈开发工程师
    《劲道》课程笔记——教练对话
    windows 7环境下配置oracle 11g 客户端
    jsp+servlet+javabean (MVC)分页
    解析java中 hashcode()
    BeanUtils操作
    Dom4jApp.java 解析和创建XML
    dom4j
  • 原文地址:https://www.cnblogs.com/okokabcd/p/8496417.html
Copyright © 2011-2022 走看看