关于互斥锁:

所谓互斥锁, 指的是一次最多只能有一个线程持有的锁. 在jdk1.5之前, 我们通常使用synchronized机制控制多个线程对共享资源的访问. 而现在, Lock提供了比synchronized机制更广泛的锁定操作, Lock和synchronized机制的主要区别:

synchronized机制提供了对与每个对象相关的隐式监视器锁的访问, 并强制所有锁获取和释放均要出现在一个块结构中, 当获取了多个锁时, 它们必须以相反的顺序释放. synchronized机制对锁的释放是隐式的, 只要线程运行的代码超出了synchronized语句块范围, 锁就会被释放. 而Lock机制必须显式的调用Lock对象的unlock()方法才能释放锁, 这为获取锁和释放锁不出现在同一个块结构中, 以及以更自由的顺序释放锁提供了可能.

关于可重入

一、2.4.1 内部锁

Java 提供了原子性的内置锁机制: sychronized 块。它包含两个部分:锁对象的引用和这个锁保护的代码块:

synchronized(lock) {

// 访问或修改被锁保护的共享状态

}

内部锁扮演了互斥锁( mutual exclusion lock, 也称作 mutex )的角色,一个线程拥有锁的时候,别的线程阻塞等待。

2.4.2 重进入(Reentrancy )

重入性:指的是同一个线程多次试图获取它所占有的锁,请求会成功。当释放锁的时候,直到重入次数清零,锁才释放完毕。

Public class Widget {

Public synchronized void doSomething(){

}

}

Public class LoggingWidget extends Widget {

Public synchronized void doSomething(){

System.out.println(toString()+”:calling doSomething”);

Super.doSomething();

}

}

二、一般来说,在多线程程序中,某个任务在持有某对象的锁后才能运行任务,其他任务只有在该任务释放同一对象锁后才能拥有对象锁,然后执行任务。于是,想到,同一个任务在持有同一个对象的锁后,在不释放锁的情况下,继续调用同一个对象的其他同步(synchronized)方法,该任务是否会再次持有该对象锁呢?

答案是肯定的。同一个任务在调用同一个对象上的其他synchronized方法,可以再次获得该对象锁。

  1. synchronized  m1(){
  2. //加入此时对锁a的计数是N
  3. m2();  //进入m2的方法体之后锁计数是N+1,离开m2后是N
  4. }
  5. synchronized m2(){}

同一任务和对象锁的问题:http://www.iteye.com/topic/728485

  1. /*public class ReentrantLock
  2. extends Object implements Lock, Serializable
  3. */

一个可重入的互斥锁 Lock,它具有与使用 synchronized 方法和语句所访问的隐式监视器锁相同的一些基本行为和语义,但功能更强大。

ReentrantLock 将由最近成功获得锁,并且还没有释放该锁的线程所拥有。当锁没有被另一个线程所拥有时,调用 lock 的线程将成功获取该锁并返回。如果当前线程已经拥有该锁,此方法将立即返回。可以使用 isHeldByCurrentThread() 和 getHoldCount() 方法来检查此情况是否发生。

此类的构造方法接受一个可选的公平 参数。当设置为 true 时,在多个线程的争用下,这些锁倾向于将访问权授予等待时间最长的线程。否则此锁将无法保证任何特定访问顺序。与采用默认设置(使用不公平锁)相比,使用公平锁的程序在许多线程访问时表现为很低的总体吞吐量(即速度很慢,常常极其慢),但是在获得锁和保证锁分配的均衡性时差异较小。不过要注意的是,公平锁不能保证线程调度的公平性。因此,使用公平锁的众多线程中的一员可能获得多倍的成功机会,这种情况发生在其他活动线程没有被处理并且目前并未持有锁时。还要注意的是,未定时的 tryLock 方法并没有使用公平设置。因为即使其他线程正在等待,只要该锁是可用的,此方法就可以获得成功。

JDK:http://www.xasxt.com/java/api/java/util/concurrent/locks/ReentrantLock.html

  1. /*构造方法摘要
  2. ReentrantLock()
  3. 创建一个 ReentrantLock 的实例。
  4. ReentrantLock(boolean fair)
  5. 创建一个具有给定公平策略的 ReentrantLock。
  6. */
  1. /**public void lock()
  2. 获取锁。
  3. 如果该锁没有被另一个线程保持,则获取该锁并立即返回,将锁的保持计数设置为 1。
  4. 如果当前线程已经保持该锁,则将保持计数加 1,并且该方法立即返回。
  5. 如果该锁被另一个线程保持,则出于线程调度的目的,禁用当前线程,并且在获得锁之前,该线程将一直处于休眠状态,此时锁保持计数被设置为 1。
  6. */

ReentrantLock 的lock机制有2种,忽略中断锁和响应中断锁,这给我们带来了很大的灵活性。比如:如果A、B 2个线程去竞争锁,A线程得到了锁,B线程等待,但是A线程这个时候实在有太多事情要处理,就是 一直不返回,B线程可能就会等不及了,想中断自己,不再等待这个锁了,转而处理其他事情。这个时候ReentrantLock就提供了2种机制,第一,B线程中断自己(或者别的线程中断它),但是ReentrantLock 不去响应,继续让B线程等待,你再怎么中断,我全当耳边风(synchronized原语就是如此);第二,B线程中断自己(或者别的线程中断它),ReentrantLock 处理了这个中断,并且不再等待这个锁的到来,完全放弃。请看例子:

Example1:

  1. package test;
  2. public interface IBuffer {
  3. public void write();
  4. public void read() throws InterruptedException;
  5. }

使用Synchronized:

  1. package test;
  2. public class Buffer implements IBuffer {
  3. private Object lock;
  4. public Buffer() {
  5. lock = this;
  6. }
  7. public void write() {
  8. synchronized (lock) {
  9. long startTime = System.currentTimeMillis();
  10. System.out.println("开始往这个buff写入数据…");
  11. for (;;)// 模拟要处理很长时间
  12. {
  13. if (System.currentTimeMillis() - startTime > Integer.MAX_VALUE)
  14. break;
  15. }
  16. System.out.println("终于写完了");
  17. }
  18. }
  19. public void read() {
  20. synchronized (lock) {
  21. System.out.println("从这个buff读数据");
  22. }
  23. }
  24. }

使用ReentrantLock:

  1. package test;
  2. import java.util.concurrent.locks.ReentrantLock;
  3. public class BufferInterruptibly implements IBuffer {
  4. private ReentrantLock lock = new ReentrantLock();
  5. public void write() {
  6. lock.lock();
  7. try {
  8. long startTime = System.currentTimeMillis();
  9. System.out.println("开始往这个buff写入数据…");
  10. for (;;)// 模拟要处理很长时间
  11. {
  12. if (System.currentTimeMillis() - startTime > Integer.MAX_VALUE)
  13. break;
  14. }
  15. System.out.println("终于写完了");
  16. } finally {
  17. lock.unlock();
  18. }
  19. }
  20. public void read() throws InterruptedException{
  21. lock.lockInterruptibly();// 注意这里,可以响应中断
  22. try {
  23. System.out.println("从这个buff读数据");
  24. } finally {
  25. lock.unlock();
  26. }
  27. }
  28. }

测试类(注意那两个线程不是内部类!):

  1. package test;
  2. public class Test {
  3. //是用ReentrantLock,还是用synchronized
  4. public static boolean useSynchronized = false;
  5. public static void main(String[] args) {
  6. IBuffer buff = null;
  7. if(useSynchronized){
  8. buff = new Buffer();
  9. }else{
  10. buff = new BufferInterruptibly();
  11. }
  12. final Writer writer = new Writer(buff);
  13. final Reader reader = new Reader(buff);
  14. writer.start();
  15. reader.start();
  16. new Thread(new Runnable() {
  17. public void run() {
  18. long start = System.currentTimeMillis();
  19. for (;;) {
  20. // 等5秒钟去中断读
  21. if (System.currentTimeMillis() - start > 5000) {
  22. System.out.println("不等了,尝试中断");
  23. reader.interrupt();
  24. break;
  25. }
  26. }
  27. }
  28. }).start();
  29. }
  30. }
  31. class Writer extends Thread {
  32. private IBuffer buff;
  33. public Writer(IBuffer buff) {
  34. this.buff = buff;
  35. }
  36. @Override
  37. public void run() {
  38. buff.write();
  39. }
  40. }
  41. class Reader extends Thread {
  42. private IBuffer buff;
  43. public Reader(IBuffer buff) {
  44. this.buff = buff;
  45. }
  46. @Override
  47. public void run() {
  48. try {
  49. buff.read();
  50. } catch (InterruptedException e) {
  51. System.out.println("我不读了");
  52. }
  53. System.out.println("读结束");
  54. }
  55. }

结果:

使用ReentrantLock时:

开始往这个buff写入数据…

不等了,尝试中断

我不读了

读结束

使用Synchronized时:

开始往这个buff写入数据…

不等了,尝试中断

实例来源:http://blog.csdn.net/quqi99/article/details/5298017

实例2:

http://junlas.iteye.com/blog/846460

实例3:

http://www.blogjava.net/killme2008/archive/2007/09/14/145195.html

重要:

一个证明可中断的例子:http://yanxuxin.iteye.com/blog/566713

关于多线程问题,signalAll,await问题:http://www.iteye.com/problems/72378

ReentrantLock :http://hujin.iteye.com/blog/479689

java的concurrent用法详解:

http://www.open-open.com/bbs/view/1320131360999

ReentrantLock-互斥同步器:

http://www.cnblogs.com/mandela/archive/2011/04/08/2009810.html

一个重要Example:

  1. package tags;
  2. import java.util.Calendar;
  3. public class TestLock {
  4. private ReentrantLock lock = null;
  5. public int data = 100;     // 用于线程同步访问的共享数据
  6. public TestLock() {
  7. lock = new ReentrantLock(); // 创建一个自由竞争的可重入锁
  8. }
  9. public ReentrantLock getLock() {
  10. return lock;
  11. }
  12. public void testReentry() {
  13. lock.lock();
  14. Calendar now = Calendar.getInstance();
  15. System.out.println(now.getTime() + " " + Thread.currentThread() + " get lock.");
  16. }
  17. public static void main(String[] args) {
  18. TestLock tester = new TestLock();
  19. //1、测试可重入
  20. tester.testReentry();
  21. tester.testReentry(); // 能执行到这里而不阻塞,表示锁可重入
  22. tester.testReentry(); // 再次重入
  23. // 释放重入测试的锁,要按重入的数量解锁,否则其他线程无法获取该锁。
  24. tester.getLock().unlock();
  25. tester.getLock().unlock();
  26. tester.getLock().unlock();
  27. //2、测试互斥
  28. // 启动3个线程测试在锁保护下的共享数据data的访问
  29. new Thread(new workerThread(tester)).start();
  30. new Thread(new workerThread(tester)).start();
  31. new Thread(new workerThread(tester)).start();
  32. }
  33. // 线程调用的方法
  34. public void testRun() throws Exception {
  35. lock.lock();
  36. Calendar now = Calendar.getInstance();
  37. try {
  38. // 获取锁后显示 当前时间 当前调用线程 共享数据的值(并使共享数据 + 1)
  39. System.out.println(now.getTime() + " " + Thread.currentThread()+ " accesses the data " + data++);
  40. Thread.sleep(1000);
  41. } catch (Exception e) {
  42. e.printStackTrace();
  43. } finally {
  44. lock.unlock();
  45. }
  46. }
  47. }
  48. // 工作线程,调用TestServer.testRun
  49. class workerThread implements Runnable {
  50. private TestLock tester = null;
  51. public workerThread(TestLock testLock) {
  52. this.tester = testLock;
  53. }
  54. public void run() {
  55. try {
  56. tester.testRun();
  57. } catch (Exception e) {
  58. e.printStackTrace();
  59. }
  60. }
  61. }

Example3:

  1. package tags;
  2. import java.util.concurrent.locks.ReentrantLock;
  3. public class ReentrantLockSample {
  4. public static void main(String[] args) {
  5. testSynchronized();
  6. //testReentrantLock();
  7. }
  8. public static void testReentrantLock() {
  9. final SampleSupport1 support = new SampleSupport1();
  10. Thread first = new Thread(new Runnable() {
  11. public void run() {
  12. try {
  13. support.doSomething();
  14. }
  15. catch (InterruptedException e) {
  16. e.printStackTrace();
  17. }
  18. }
  19. });
  20. Thread second = new Thread(new Runnable() {
  21. public void run() {
  22. try {
  23. support.doSomething();
  24. }
  25. catch (InterruptedException e) {
  26. System.out.println("Second Thread Interrupted without executing counter++,beacuse it waits a long time.");
  27. }
  28. }
  29. });
  30. executeTest(first, second);
  31. }
  32. public static void testSynchronized() {
  33. final SampleSupport2 support2 = new SampleSupport2();
  34. Runnable runnable = new Runnable() {
  35. public void run() {
  36. support2.doSomething();
  37. }
  38. };
  39. Thread third = new Thread(runnable);
  40. Thread fourth = new Thread(runnable);
  41. executeTest(third, fourth);
  42. }
  43. /**
  44. * Make thread a run faster than thread b,
  45. * then thread b will be interruted after about 1s.
  46. * @param a
  47. * @param b
  48. */
  49. public static void executeTest(Thread a, Thread b) {
  50. a.start();
  51. try {
  52. Thread.sleep(100);
  53. b.start(); // The main thread sleep 100ms, and then start the second thread.
  54. Thread.sleep(1000);
  55. // 1s later, the main thread decided not to allow the second thread wait any longer.
  56. b.interrupt();
  57. }
  58. catch (InterruptedException e) {
  59. e.printStackTrace();
  60. }
  61. }
  62. }
  63. abstract class SampleSupport {
  64. protected int counter;
  65. /**
  66. * A simple countdown,it will stop after about 5s.
  67. */
  68. public void startTheCountdown() {
  69. long currentTime = System.currentTimeMillis();
  70. for (;;) {
  71. long diff = System.currentTimeMillis() - currentTime;
  72. if (diff > 5000) {
  73. break;
  74. }
  75. }
  76. }
  77. }
  78. class SampleSupport1 extends SampleSupport {
  79. private final ReentrantLock lock = new ReentrantLock();
  80. public void doSomething() throws InterruptedException {
  81. lock.lockInterruptibly(); // (1)
  82. System.out.println(Thread.currentThread().getName() + " will execute counter++.");
  83. startTheCountdown();
  84. try {
  85. counter++;
  86. }
  87. finally {
  88. lock.unlock();
  89. }
  90. }
  91. }
  92. class SampleSupport2 extends SampleSupport {
  93. public synchronized void doSomething() {
  94. System.out.println(Thread.currentThread().getName() + " will execute counter++.");
  95. startTheCountdown();
  96. counter++;
  97. }
  98. }

在这个例子中,辅助类SampleSupport提供一个倒计时的功能startTheCountdown(),这里倒计时5s左右。SampleSupport1,SampleSupport2继承其并分别的具有doSomething()方法,任何进入方法的线程会运行5s左右之后counter++然后离开方法释放锁。SampleSupport1是使用ReentrantLock机制,SampleSupport2是使用synchronized机制。

testSynchronized()和testReentrantLock()都分别开启两个线程执行测试方法executeTest(),这个方法会让一个线程先启动,另一个过100ms左右启动,并且隔1s左右试图中断后者。结果正如之前提到的第二点:interrupt()对于synchronized是没有作用的,它依然会等待5s左右获得锁执行counter++;而ReentrantLock机制可以保证在线程还未获得并且试图获得锁时如果发现线程中断,则抛出异常清除中断标记退出竞争。所以testReentrantLock()中second线程不会继续去竞争锁,执行异常内的打印语句后线程运行结束。

来源:http://yanxuxin.iteye.com/blog/566713

Example4:

三个线程,线程名分别为A、B、C,设计程序使得三个线程循环打印“ABC”10次后终止。如:ABCABCABCABCABCABCABCABCABCABC

  1. package tags;
  2. import java.util.concurrent.locks.ReentrantLock;
  3. public class ReentrantLockPractice {
  4. static ReentrantLock lock = new ReentrantLock();
  5. private static String[] threadArr = {"A","B","C"};
  6. public static void main(String[] args){
  7. ReentrantLockPractice pc = new ReentrantLockPractice();
  8. pc.startDemo();
  9. }
  10. void startDemo(){
  11. for(int i = 0;i<10;i++){
  12. for(String name : threadArr){
  13. TestThread t = new TestThread(name);
  14. t.start();
  15. try {
  16. Thread.sleep(100);
  17. } catch (InterruptedException e) {
  18. e.printStackTrace();
  19. }
  20. }
  21. }
  22. }
  23. class TestThread extends Thread{
  24. //自定义线程名字
  25. TestThread(String str){
  26. super(str);
  27. }
  28. public void run(){
  29. try {
  30. lock.lockInterruptibly();
  31. System.out.print(Thread.currentThread().getName());
  32. } catch (InterruptedException e) {
  33. e.printStackTrace();
  34. } finally{
  35. lock.unlock();
  36. }
  37. }
  38. }
  39. }

注意与Example2的区别,一个线材类定义在内部,一个在外部,注意区别。

其他方法:

http://hxraid.iteye.com/blog/607228

相同:ReentrantLock提供了synchronized类似的功能和内存语义。

不同:

1.ReentrantLock功能性方面更全面,比如时间锁等候,可中断锁等候,锁投票等,因此更有扩展性。在多个条件变量和高度竞争锁的地方,用ReentrantLock更合适,ReentrantLock还提供了Condition,对线程的等待和唤醒等操作更加灵活,一个ReentrantLock可以有多个Condition实例,所以更有扩展性。

2.ReentrantLock必须在finally中释放锁,否则后果很严重,编码角度来说使用synchronized更加简单,不容易遗漏或者出错。

3.ReentrantLock 的性能比synchronized会好点。

4.ReentrantLock提供了可轮询的锁请求,他可以尝试的去取得锁,如果取得成功则继续处理,取得不成功,可以等下次运行的时候处理,所以不容易产生死锁,而synchronized则一旦进入锁请求要么成功,要么一直阻塞,所以更容易产生死锁。

1、Lock的某些方法可以决定多长时间内尝试获取锁,如果获取不到就抛异常,这样就可以一定程度上减轻死锁的可能性。

如果锁被另一个线程占据了,synchronized只会一直等待,很容易错序死锁

2、synchronized的话,锁的范围是整个方法或synchronized块部分;而Lock因为是方法调用,可以跨方法,灵活性更大 

3、便于测试,单元测试时,可以模拟Lock,确定是否获得了锁,而synchronized就没办法了

ReentrantLock比synchronized 强大在哪儿?

简单说:

1、ReentrantLock可以实现fair lock 

public ReentrantLock(boolean fair) {

sync = (fair)? new FairSync() : new NonfairSync();

}

所谓fair lock就是看获得锁的顺序是不是和申请锁的时间的顺序是一致的 

2、ReentrantLock支持中断处理 

public final void acquireInterruptibly(int arg) throws InterruptedException {

if (Thread.interrupted())

throw new InterruptedException();

if (!tryAcquire(arg))

doAcquireInterruptibly(arg);

}

就是说那些持有锁的线程一直不释放,正在等待的线程可以放弃等待。

3、ReentrantLock可以和condition结合使用

public boolean hasWaiters(Condition condition) {

if (condition == null)

throw new NullPointerException();

if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))

throw new IllegalArgumentException("not owner");

return sync.hasWaiters((AbstractQueuedSynchronizer.ConditionObject)condition);

}

public int getWaitQueueLength(Condition condition) {

if (condition == null)

throw new NullPointerException();

if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))

throw new IllegalArgumentException("not owner");

return sync.getWaitQueueLength((AbstractQueuedSynchronizer.ConditionObject)condition);

}

内置锁synchronized

显式锁Lock

ReentrantLock代码剖析之ReentrantLock.lock

ReentrantLock中tryLock的使用问题(注意循环)

synchronized是可重入锁

如果一个获取锁的线程调用其它的synchronized修饰的方法,会发生什么?

从设计上讲,当一个线程请求一个由其他线程持有的对象锁时,该线程会阻塞。当线程请求自己持有的对象锁时,如果该线程是重入锁,请求就会成功,否则阻塞。

我们回来看synchronized,synchronized拥有强制原子性的内部锁机制,是一个可重入锁。因此,在一个线程使用synchronized方法时调用该对象另一个synchronized方法,即一个线程得到一个对象锁后再次请求该对象锁,是永远可以拿到锁的。

在Java内部,同一个线程调用自己类中其他synchronized方法/块时不会阻碍该线程的执行,同一个线程对同一个对象锁是可重入的,同一个线程可以获取同一把锁多次,也就是可以多次重入。原因是Java中线程获得对象锁的操作是以线程为单位的,而不是以调用为单位的。

synchronized可重入锁的实现

每个锁关联一个线程持有者和一个计数器。当计数器为0时表示该锁没有被任何线程持有,那么任何线程都都可能获得该锁而调用相应方法。当一个线程请求成功后,JVM会记下持有锁的线程,并将计数器计为1。此时其他线程请求该锁,则必须等待。而该持有锁的线程如果再次请求这个锁,就可以再次拿到这个锁,同时计数器会递增。当线程退出一个synchronized方法/块时,计数器会递减,如果计数器为0则释放该锁。

ReentrantLock synchronized的更多相关文章

  1. synchronized 和 ReentrantLock 区别

    synchronized 使用: 1:当一个线程访问object的一个synchronized(this)同步代码块时,它就获得了这个object的对象锁.结果,其它线程对该object对象所有同步代 ...

  2. 死磕 java同步系列之ReentrantLock VS synchronized——结果可能跟你想的不一样

    问题 (1)ReentrantLock有哪些优点? (2)ReentrantLock有哪些缺点? (3)ReentrantLock是否可以完全替代synchronized? 简介 synchroniz ...

  3. Java进阶知识点:不要只会写synchronized - JDK十大并发编程组件总结

    一.背景 提到Java中的并发编程,首先想到的便是使用synchronized代码块,保证代码块在并发环境下有序执行,从而避免冲突.如果涉及多线程间通信,可以再在synchronized代码块中使用w ...

  4. Java进阶知识点7:不要只会写synchronized - JDK十大并发编程组件总结

    一.背景 提到Java中的并发编程,首先想到的便是使用synchronized代码块,保证代码块在并发环境下有序执行,从而避免冲突.如果涉及多线程间通信,可以再在synchronized代码块中使用w ...

  5. 用阻塞队列实现一个生产者消费者模型?synchronized和lock有什么区别?

    多线程当中的阻塞队列 主要实现类有 ArrayBlockingQueue是一个基于数组结构的有界阻塞队列,此队列按FIFO原则对元素进行排序 LinkedBlockingQueue是一个基于链表结构的 ...

  6. Java并发编程二三事

    Java并发编程二三事 转自我的Github 近日重新翻了一下<Java Concurrency in Practice>故以此文记之. 我觉得Java的并发可以从下面三个点去理解: * ...

  7. 201521123013 《Java程序设计》第11周学习总结

    1. 本章学习总结 2. 书面作业 Q1.1.互斥访问与同步访问 完成题集4-4(互斥访问)与4-5(同步访问) 1.1 除了使用synchronized修饰方法实现互斥同步访问,还有什么办法实现互斥 ...

  8. 201521044091 《Java程序设计》第11周学习总结

    1. 本章学习总结 2. 书面作业 Q1.1.互斥访问与同步访问完成题集4-4(互斥访问)与4-5(同步访问) 1.1 除了使用synchronized修饰方法实现互斥同步访问,还有什么办法实现互斥同 ...

  9. Java高并发--AQS

    Java高并发--AQS 主要是学习慕课网实战视频<Java并发编程入门与高并发面试>的笔记 AQS是AbstractQueuedSynchronizer的简称,直译过来是抽象队列同步器. ...

随机推荐

  1. css 填坑常用代码分享[居家实用型]

    原文地址 http://www.cnblogs.com/jikey/p/4233003.html 以下是常用的代码收集,没有任何技术含量,只是填坑的积累.转载请注明出处,谢谢. 一. css 2.x ...

  2. EINTR与ERESTARTSYS

    驱动中如果down_interruptible之类的函数被信号中断,驱动可以返回-EINTR或-ERESTARTSYS. 区别在于: 若返回-EINTR,应用程序执行的系统调用会返回表示错误的值,且e ...

  3. 【Servlet和JSP-学习-1】基础知识

    Servlet Session管理 Cookie 获取指定名称的Cookie 删除指定名称的Cookie JSP EL表达式 示例: 后台存入request中的属性值: JSP界面 JSTL 来自为知 ...

  4. 十二、jdk工具之jcmd介绍(堆转储、堆分析、获取系统信息、查看堆外内存)

    目录 一.jdk工具之jps(JVM Process Status Tools)命令使用 二.jdk命令之javah命令(C Header and Stub File Generator) 三.jdk ...

  5. SQL中select与set的区别

    转自 : http://www.cnblogs.com/4mylife/archive/2012/10/25/2738466.html 下表列出 SET 与 SELECT 的区别   SELECT S ...

  6. javascript创建对象之寄生构造函数模式(六)

    这种模式的基本思想是创建一个函数,该函数的作用仅仅是封装创建对象的代码,然后再返回新创建的对象; 但是从表面上看,这个函数有很像典型的构造函数. function createHuman(name,s ...

  7. blktrace分析IO

    http://bean-li.github.io/blktrace-to-report/ 前言 上篇博客介绍了iostat的一些输出,这篇介绍blktrace这个神器.上一节介绍iostat的时候,我 ...

  8. ORM PetaPoco 框架的 CRUD 操作

    PetaPoco 的查询操作 public IEnumerable<T> GetAll(string sqlString, object[] obj) { try { IEnumerabl ...

  9. ORM 框架简介

    对象-关系映射(Object/Relation Mapping,简称ORM),是随着面向对象的软件开发方法发展而产生的.面向对象的开发方法是当今企业级应用开发环境中的主流开发方法,关系数据库是企业级应 ...

  10. 并发工具类(四)线程间的交换数据 Exchanger

    前言   JDK中为了处理线程之间的同步问题,除了提供锁机制之外,还提供了几个非常有用的并发工具类:CountDownLatch.CyclicBarrier.Semphore.Exchanger.Ph ...