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);
    	}
    }
  • 相关阅读:
    USASO Greedy Gift Givers
    Mat 类型用法
    OpenCV错误:Unhandled exception at 0x0133bc63 ....0xC0000005: Access violation reading location 0x00000004.
    C++ seekp 函数文件流跳转功能产生数据覆盖问题解决
    C++中文件名称必须是C风格的char*格式
    char*, char[] ,CString, string的转换
    Visual Stdio 2008 最大内存分配块大小问题: 使用new 分配连续723M内存 出错 std::bad_alloc at memory location 0x0013e0b8
    string类型转化为char*错误: error C2440: '=' : cannot convert from 'const char *' to 'char *'
    Mat 和 IplImage、CvMat格式的互相转换
    指针数组和数组指针
  • 原文地址:https://www.cnblogs.com/new0801/p/6146611.html
Copyright © 2011-2022 走看看