soa---java 多线程的---锁
如今soa 与分布式计算已经成为互联网公司技术的标配
那他包括的知识点应该熟悉了解。并以此为基础,去应用,调优各种soa的框架。
包括例如以下的四点。是分布式的基础。
        a java 多线程 承接高吞吐量。
        b java nio 承接高并发,与交互协议的定制。
c java 反射 完毕序列化与反序列化。
d 设计模式的应用 保证应用的扩展性。
接上篇
由于说锁的原理比較的枯燥,得带着问题场景去说。才干看下去。才干研究下去。
在Java中Lock接口比synchronized块的优势是什么?你须要实现一个高效的缓存。它同意多个用户读,但仅仅同意一个用户写,以此来保持它的完整性,你会如何去实现它?
这里主要是要考察说lock与synchronized 的差别。
1 利用cpu底层机制lock有读锁 与 写锁的区分。
2 在于上下文的切换与锁的竞争的优化。
3 关于死锁的避免
Synchronized 仅仅是jvm里面自己的一个协议;
而关于这个Lock 他的底层里面是有硬件支持的原子操作,各种cpu都支持的,各种平台也支持。假设须要具体理解。能够看看里面的源代码,里面有一个重要的类就是AbstractQueuedSynchronizer, 它是轮询处理。
synchronized 在取不到锁的时候。会休眠一段时间。这样要说开销非常大。
当然这样的synchronized 内部是后面的版本号能够进行优化的。
  
1 利用cpu底层机制lock有读锁 与 写锁的区分。
那实现上面题干的两种方式例如以下
synchronized样例
代码例如以下
public class SynchronizedMap<K,V> {
 private final Map<K,V> map=new HashMap<K, V>();
   public synchronized void put(K k,V v){
    map.put(k, v);
   }
   public synchronized V get(K k){
    return map.get(k);
   }
这样的排斥了 写/写,读/写 读/读。
对于lock,相关代码例如以下。
public class LockMap<K, V> {
 private final Map<K, V> map=new HashMap<K, V>();
 private final ReadWriteLock lock=new ReentrantReadWriteLock();
 private final Lock r=lock.readLock();
 private final Lock w=lock.writeLock();
 public void put(K key,V value){
  w.lock();
  try {
   map.put(key, value);
  } catch (Exception e) {
   e.printStackTrace();
  }finally{
   w.unlock();
  }
 }
 public V get(K key){
  r.lock();
  try {
   return map.get(key);
  } catch (Exception e) {
   e.printStackTrace();
  }finally{
   r.unlock();
  }
  return null;
 }
}
这样的排斥了 写/写 读/写 。
但读/读没有排斥。
也是就说读与读是多个线程能够同一时候读的。----能够做为读多写少的应用。
2在于上下文的切换与锁的竞争的优化。
对于 synchronized 来说。
他仅仅有一个条件队列的。里面放着相应于不同类型的(也能够说是处理不同业务类型的)线程。那这时。你仅仅能notifyall
    。为了保证程序的正确,把全部的线程都叫起来,无论是不是你想要的业务类型的线程。这样的对于性能影响是很大的。比方10个线程在一个条件队列上等待,那么调用notifyAll 将唤醒全部的线程
   这个时候线程产生例如以下:
       a 它们会在锁上面产生竞争。
       b 它们竞争完了之后大部分又大部分wait了
         这两步。会导致了大量的线程上下文切换。
以及大量锁的竞争。
但这个lock是没问题的。他能够对于 不同的条件创建wait-set ,比方生产者消费者模式。生产者生产一个对象。这时想唤醒消费者。仅仅须要在对应的条件上面的wait set进行single.
对于线程安全的lock队列,与线程安全的synchronized stack代码
synchronized 代码例如以下
public class ProductStack {
	private Product[] products=new Product[10];
	private int index;
	public synchronized void addProduct(Product product){
		try {
			while(index>=(products.length-1)){//须要又一次检查一下。条件推断s
				System.out.println(" the product array is full ; "+Thread.currentThread().getName()+" is waiting");
				wait();
			}
				products[index]=product;
				index++;
				notifyAll();//为了能启动消费线程 当然也唤醒了生产线程。
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	public synchronized Product pop(){
		Product product=null;
		try {
			while(index<=0){ //须要又一次检查一下。条件推断
				System.out.println("the product array is empty ;"+Thread.currentThread().getName() +"is waiting");
				wait();
			}
			    index--;
			    product=products[index];
				notifyAll();   //为了能启动 加入线程。 当然也唤醒了消费线程。
		} catch (Exception e) {
			e.printStackTrace();
		}
		return product;
	}
}
对于lock
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock; public class ProductQueue<V> {
private final static int defaultSize=10;
private final V[] queue;
private int total;
private int tail;
private int head;
private Lock lock=new ReentrantLock();
private Condition notEmpty=lock.newCondition();
private Condition notFull= lock.newCondition(); public ProductQueue(){ this(defaultSize);
} public ProductQueue(int initialCapacity) {
super();
this.queue = (V[])new Object[initialCapacity];
} public void push(V v) throws InterruptedException{
lock.lock();
try {
while (isFull()) {
notFull.await();
} queue[tail] = v;
++tail;
if (tail == queue.length)
tail = 0;
total++;
notEmpty.signal();//唤醒的是同一种类型的线程,不会浪费。 } finally{
lock.unlock();
} } public V pop() throws InterruptedException{
lock.lock();
try {
while(isEmpty()){
notEmpty.await();
}
V v=queue[head];
head++;
if(head==queue.length)head=0;
total--;
notFull.signal();//唤醒的是同一种类型的线程,不会浪费。
return v;
} finally{
lock.unlock();
}
} public boolean isEmpty(){
return total==0;
}
public boolean isFull(){
return total==queue.length;
} }
注解里面解释到了问题的根本。
notifyall 时将全部的线程,生产者,消费者都唤醒了。而此时你仅仅想唤醒生产者,或者仅仅想唤醒消费者,让你胡子眉毛一把抓
3 关于死锁的避免
产生死锁的本质:至少有两把以上的锁,每一个线程获取锁的方式不会一样。实际应用中会有例如以下3种情况,出现死锁
a  同一类对象
    第一个方法
       synchronized(LockA){
                synchronized(LockB){
                       }
         }
                                  
       第二个方法
              synchronized(LockB){
                   synchronized(LockA){
                             doSomeThing.......
                  }
             }
   以上情况的解决方式是。顺序不一样。把顺序搞一样就成。
  b 对于方法 public void A(SameObject a,SameObject b){
                            synchronized(a){
                                                 synchronized(b){
                                                                                                    doSomeThing.......
                                                        }
                                                            }
                        }
 这里会产生死锁的可能,原因是依据參数的顺序就能有可能被锁了。 这时能够用并发包里面的tryLock最简单。         以上是在同一个类里面。
b  这样的情况,是在两个类里面。能够想象成为两个资源。
                       在类A里面的有一个a 方法是同步的。
                       在类B里面的有一个b 方法是同步的。
                       a 里面调b方法。
b 里面调a方法。
    这里就会产生死锁,由于获取锁的顺序不一样。 这样的情况的解决方式是,将方法上的全部的synchronized的都去掉,换成同步块。但同步块同是将传过来的资源。进行一个copy. 这个在并发包里面的有些集合能够參考的。
全局,分析锁的个数。获取的顺序。顺序好说,那怎么分析?
怎么去分析死锁呢?
a 争取用同步块,把不能同步方法。从业务角度保证开方式调用。
b 用线程堆栈信息来分析(kill -3)的方式。
c 对于业务的拆解。
理论上没有死锁,可是锁管理的资源。在线程处理的时候,占时太长,将业务就要进行重构了。
d 加一功能代码 代码例如以下
ThreadMXBean tmx = ManagementFactory.getThreadMXBean();
long[] ids = tmx.findDeadlockedThreads();
if (ids != null) {
ThreadInfo[] infos = tmx.getThreadInfo(ids, true, true);
System.out.println("The following threads are deadlocked:");
for (ThreadInfo ti : infos) {
System.out.println(ti);
}
}
soa---java 多线程的---锁的更多相关文章
- JAVA多线程与锁机制
		JAVA多线程与锁机制 1 关于Synchronized和lock synchronized是Java的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码 ... 
- Java 多线程:锁(一)
		Java 多线程:锁(一) 作者:Grey 原文地址: 博客园:Java 多线程:锁(一) CSDN:Java 多线程:锁(一) CAS 比较与交换的意思 举个例子,内存有个值是 3,如果用 Java ... 
- Java 多线程:锁(二)
		Java 多线程:锁(二) 作者:Grey 原文地址: 博客园:Java 多线程:锁(二) CSDN:Java 多线程:锁(二) AtomicLong VS LongAddr VS Synchroni ... 
- Java 多线程:锁(三)
		Java 多线程:锁(三) 作者:Grey 原文地址: 博客园:Java 多线程:锁(三) CSDN:Java 多线程:锁(三) StampedLock StampedLock其实是对读写锁的一种改进 ... 
- java多线程----悲观锁与乐观锁
		java多线程中悲观锁与乐观锁思想 一.悲观锁 总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻塞直到它拿到锁(共享资源每次只给一个线 ... 
- (转)java 多线程 对象锁&类锁
		转自:http://blog.csdn.net/u013142781/article/details/51697672 最近工作有用到一些多线程的东西,之前吧,有用到synchronized同步块,不 ... 
- java多线程之锁 -- 偏向锁、轻量级锁、自旋锁、重量级锁
		转载至:https://blog.csdn.net/zqz_zqz/article/details/70233767 之前做过一个测试,详情见这篇文章<多线程 +1操作的几种实现方式,及效率对比 ... 
- Java多线程--公平锁与非公平锁
		上一篇文章介绍了AQS的基本原理,它其实就是一个并发包的基础组件,用来实现各种锁,各种同步组件的.它包含了state变量.加锁线程.等待队列等并发中的核心组件,现在我们来看一下多线程获取锁的顺序问题. ... 
- java多线程编程——锁优化
		并发环境下进行编程时,需要使用锁机制来同步多线程间的操作,保证共享资源的互斥访问.加锁会带来性能上的损坏,似乎是众所周知的事情.然而,加锁本身不会带来多少的性能消耗,性能主要是在线程的获取锁的过程.如 ... 
- Java多线程之锁优化策略
		转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/6561264.html 锁的优化策略 编码过程中可采取的锁优化的思路有以下几种: 1:减少锁持有时间 例如:对 ... 
随机推荐
- 如何使用VisualStudio2013编写和调试c语言程序
			觉得很多基础学习者对VS不太熟悉,我就转一篇觉得还不错的.转自:http://jingyan.baidu.com/article/f3ad7d0fe7ca0d09c3345b84.html 现在大多数 ... 
- 基于ZigBee和STM32的智能家居控制系统的设计与实现(三)
			基于ZigBee和STM32的智能家居控制系统的设计与实现(三) 自从前两篇博客介绍了智能家居系统的基本实现机理后,收到了好多朋友的来信,和我讨论了好多的这方面的知识,在此很高兴,虽然自己做的这个所谓 ... 
- iOS开发-自定义UIAlterView(iOS 7)
			App中不可能少了弹框,弹框是交互的必要形式,使用起来也非常简单,不过最近需要自定义一个弹框,虽然iOS本身的弹框已经能满足大部分的需求,但是不可避免还是需要做一些自定义的工作.iOS7之前是可以自定 ... 
- 用Visual C#来清空回收站(1)
			视窗操作系统的回收站是对文件一种保护措施,他主要是作用是不言而喻的.在新的视窗2000系统之中,当我把文件删除到回收站中以后,按动"清空回收站"按钮,想清空回收站,此时往往提示&q ... 
- 第一个手写Win32窗口程序
			第一个手写Win32窗口程序 一 Windows编程基础 1 Win32应用程序的基本类型 1.1 控制台程序 不需要完善的Windows窗口,可以使用DOS窗口 的方式显示. 1.2 Win32窗口 ... 
- Lucene的查询语法,JavaCC及QueryParser(1)
			http://www.cnblogs.com/forfuture1978/archive/2010/05/08/1730200.html 一.Lucene的查询语法 Lucene所支持的查询语法可见h ... 
- T 分布(近似标准正态分布)
			1.1 定义 定义:假设X服从标准正态分布N(0,1),Y服从卡方分布,那么的分布称为自由度为n的t分布,记为. T分布密度函数其中,Gam(x)为伽马函数. 可用于两组独立计量资料的假设检 ... 
- how to restrict copy paste in a Textbox, in MFC?
			[问题] I am developing a small application in MFC... there is a little problem..hope you guys would he ... 
- Direct2D教程IV——笔刷(Brush)对象
			目前博客园中成系列的Direct2D的教程有 1.万一的 Direct2D 系列,用的是Delphi 2009 2.zdd的 Direct2D 系列,用的是VS中的C++ 3.本文所在的 Direct ... 
- 启动IntelliJ IDEA 2016报错:cannot start under Java 1.7 : Java 1.8 or later is required 解决办法
			idea64.exe启动错误:Cannot start under Java 1.7.0xxx IntelliJ IDEA : Unsupported java version Cannot star ... 
