zoukankan      html  css  js  c++  java
  • java同步synchronized

    java同步synchronized

          volatile仅仅用来保证该变量对所有线程的可见性,但不保证原子性。

          下面的这段代码:

    /**
     * 
     * @author InJavaWeTrust
     *
     */
    public class CountVolatile implements Runnable {
    	public static CountVolatile instance = new CountVolatile();
    	public static volatile int i = 0;
    	public static void increate() {
    		i++;
    	}
    	public void run() {
    		for (int c = 0; c < 10000000; c++) {
    			increate();
    		}
    	}
    	public static void main(String[] args) throws InterruptedException {
    		Thread t1 = new Thread(instance);
    		Thread t2 = new Thread(instance);
    		t1.start();
    		t2.start();
    		t1.join();
    		t2.join();
    		System.out.println(i);
    	}
    }

             段代码演示了一个计数器,两个线程同时对i进行累加,个执行10000000次。我们希望的执行结果是最终i的值可以达到20000000,但事实并非总是如此。很多时候,i的值会小于期望的数值20000000。这是因为两个线程同时对i进行写入时,其中一个线程的结果会覆盖另外一个线程的结果。

           从根本上解决这个问题,我们就必须保证多个线程在对i进行操作时完全同步。

           关键字synchronized的作用是实现线程间的同步。当它锁定一个方法或者一个代码块的时候,同一时刻最多只有一个线程执行这段代码。当两个并发线程访问同一个对象object中的这个加锁同步代码块时,一个时间内只能有一个线程得到执行。另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块。

           关键字synchronized的几种用法。

    • 指定加锁对象:对给定对象加锁,进入同步代码钱要获得给定对象的锁。
    • 直接作用于实例方法:相当于对当前实例加锁,进入同步代码前要获得当前实例的锁。
    • 直接作用于静态方法:相当于对当前类加锁,进入同步代码前要获得当前类的锁。

    一、指定加锁对象:

    /**
     * 
     * @author InJavaWeTrust
     *
     */
    public class CountSynchronized implements Runnable {
    	public static CountSynchronized instance = new CountSynchronized();
    	public static int i = 0;
    	public void run() {
    		for (int c = 0; c < 10000000; c++) {
    			synchronized(instance) { //对给定对象加锁
    				i++;
    			}
    		}
    	}
    	
    	public static void main(String[] args) throws InterruptedException {
    		Thread t1 = new Thread(instance);
    		Thread t2 = new Thread(instance);
    		t1.start();
    		t2.start();
    		t1.join();
    		t2.join();
    		System.out.println(i);
    	}
    }

      

    二、直接作用于实例方法:

    /**
     * 
     * @author InJavaWeTrust
     *
     */
    public class CountSynchronized2 implements Runnable {
    	public static CountSynchronized2 instance = new CountSynchronized2();
    	public static int i = 0;
    	public synchronized void increate() { //对当前实例方法加锁
    		i++;
    	}
    	public void run() {
    		for (int c = 0; c < 10000000; c++) {
    			increate();
    		}
    	}
    	
    	public static void main(String[] args) throws InterruptedException {
    		Thread t1 = new Thread(instance);
    		Thread t2 = new Thread(instance);
    		t1.start();
    		t2.start();
    		t1.join();
    		t2.join();
    		System.out.println(i);
    	}
    }

    三、直接作用于静态方法:

    /**
     * 
     * @author InJavaWeTrust
     *
     */
    public class CountStaticMethod implements Runnable {
    	static int i = 0;
    	public static synchronized void increate() { //相当于对当前类加锁
    		i++;
    	}
    	public void run() {
    		for (int c = 0; c < 10000000; c++) {
    			increate();
    		}
    	}
    	
    	public static void main(String[] args) throws InterruptedException {
    		Thread t1 = new Thread(new CountStaticMethod());//new一个对象
    		Thread t2 = new Thread(new CountStaticMethod());//new一个对象
    		t1.start();
    		t2.start();
    		t1.join();
    		t2.join();
    		System.out.println(i);
    	}
    }
  • 相关阅读:
    一个母亲一生撒的八个谎言(含泪推荐)!
    穷人必须做的四件大事
    八种人不太可能驰骋职场,有你吗?
    是谁让我如此忧伤?
    拒绝平淡:我用十年的时间名满天下
    高性能利器!华为云MRS ClickHouse重磅推出!
    MySQL 连接为什么挂死了?
    解读登录双因子认证(MFA)特性背后的TOTP原理
    云图说|初识数据仓库服务:云时代的数据分析助手
    号外!5G+X联创营华为云官网上线,5G 创业春天来了!
  • 原文地址:https://www.cnblogs.com/new0801/p/6146611.html
Copyright © 2011-2022 走看看