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。

  • 相关阅读:
    python 多核并行计算 示例3,使用 管道 Pipe(仅仅作为记录)
    python 多核并行计算 示例2,使用manager 进行进程共享(仅仅作为记录)
    python 多核并行计算 示例1(工作太忙,仅仅作为记录)
    python多线程示例3,加锁(仅仅作为记录)
    python多线程示例2,加锁(仅仅作为记录)
    python多线程示例1(工作太忙,仅仅作为记录)
    C中字符串分割函数strtok的一个坑(转)
    外扩闪存Quad-SPIFlash(转)
    ARM交叉编译器_说明(转)
    echarts-柱状图-圆柱
  • 原文地址:https://www.cnblogs.com/okokabcd/p/8496417.html
Copyright © 2011-2022 走看看