• Java 并发编程实践


    一、线程安全

    1、原子操作。使用java5中的并发库的原子变量可以解决多线程并发访问同一个共享变量。

    2、锁

    如果对象中有多个共享数据的读写,在多线程环境中,有可能有死锁的情况发生。这时需要用synchronized来控制对共享数据的读写。这里有个概念叫重入(reentrancy)。

    可以这么理解:当一个锁被某个线程持有,那么其他线程不可再获取这把锁,但是持有这把锁的线程可以重新持有。其实在运行时环境中有一个对同步锁计数的机制,即锁空闲态时候,count=0,当某个线程持有这把锁后count++,并记录这把锁的owner,当持有这把锁的线程再次持有这把锁后继续count++。

    	public class Widget {
    		public synchronized void doSomething() {
    			// ...
    		}
    	}
    
    	public class LoggingWidget extends Widget {
    		public synchronized void doSomething() {
    			System.out.println(toString() + ": calling doSomething");
    			//如果没有重入的机制,这里会产生死锁
    			super.doSomething();
    		}
    	}

    3、用锁保存状态

        如何正确使用锁机制,要根据实际情况有一个合适的力度,不能随随便的就把某个方法直接synchronized(可能将不需要同步的部分也加锁,那么对性能造成了一定的影响),也不能将read-modify-write的某一个或者两个操作放入原子操作(没有正确分析原子操作构成)。

        对于调用中的多个变量中的每个变量,都必须要持有同一个锁。

    二、共享对象

    1、可见性

    In the absence of synchronization, the compiler, processor, and runtime
    can do some downright weird things to the order in which operations ap-
    pear to execute. Attempts to reason about the order in which memory
    actions “must” happen in insufficiently synchronized multithreaded pro-
    grams will almost certainly be incorrect.

    简单的来说,就是多线程的环境下,情况是多变而复杂的,所以,对于需要读写的变量,最好的方法就是synchronized 。

    锁与可见性

    书中的图很好的描述了该问题

    image

    Volatile Variables 可变变量:程度较轻的 synchronized”

    非volatile变量在多线程运行环境中, 在每个线程中有一块临时内存存放,也就去他们的访问的事各自临时内存块的数据,而volatile变量则是放在一个公共的环境共多线程访问,即达到了可见性。

    2、Publication and escape 公开与逃逸

    在JAVA中,通过public,protect,private等方法可以控制对象的访问权限,但是如果你处理不当,可能会使有的不应该被访问的数据被处理。

    	class UnsafeStates {
    		private String[] states = new String[] { "AK", "AL" // ...
    		};
    		public String[] getStates() {
    			return states;
    		}
    	}

    返回的states变量是一个数组地址,调用方法是可以修改该数组的值。

    3、Thread Confinement线程限制

    堆限制:局部变量是线程相关的,所以只要改局部变量没有逃逸,就保证是线程安全的。

    ThreadLocal:每个线程都保存在一个键值对中,取出的时候只取出和本线程相关的值。典型的用空间换时间,比较常见在连接池中使用。

    不变:不变的对象是线程安全的,这种对象是创建完了以后,只读。一般是用final修饰。

    4、安全发布

  • 相关阅读:
    java 24
    java 24
    java 24
    java 24
    一个用httpPost,get访问外网接口,参数json,返回json的示例
    几个强大的oracle自带函数,可根据日期算年纪,根据数值匹配字段
    sql对日期的处理,一个存储过程示例
    一条sql,有分页,表合并查询,多表连接,用于oracle数据库
    后台返回data直接在页面转换
    JQuery的$和其它JS发生冲突的快速解决方法
  • 原文地址:https://www.cnblogs.com/sodmecai/p/2526596.html
Copyright © 2020-2023  润新知