<file_sep>/**
 * 版权申明
 */
package com.mj.currencyprogramming.step8;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.Exchanger;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @Title ExchangerUse.java
 * @Description Exchanger简单使用
 * @Date 2015/11/25 14:48
 * @Author jiayi <EMAIL>
 * @Version 2.0
 */
public class ExchangerUse {
    static Exchanger<String> exchanger = new Exchanger<String>();
    static ThreadPoolExecutor executor = new ThreadPoolExecutor(2,2,0, TimeUnit.SECONDS,new ArrayBlockingQueue<Runnable>(10));

    public static void main(String[] args) {
//        System.out.println(Runtime.getRuntime().availableProcessors());
        executor.execute(new Runnable() {
            public void run() {
                String A = "银行流水A";
                try {
                    exchanger.exchange(A);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        executor.execute(new Runnable() {
            public void run() {
                String B = "银行流水B";
                try {
                    String tmp = exchanger.exchange(B);
                    System.out.println("A和B数据是否一致："+B.equals(tmp)+"\nA数据："+tmp+"\nB数据："+B);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        executor.shutdown();
    }
}
<file_sep>/**
 * 版权申明
 */
package com.mj.currencyprogramming.step8;

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

/**
 * @Title CyclicBarrierUse.java
 * @Description CyclicBarrier简单使用
 * @Date 2015/11/25 11:12
 * @Author jiayi <EMAIL>
 * @Version 2.0
 */
public class CyclicBarrierUse {
    static CyclicBarrier cyclicBarrier = new CyclicBarrier(2);
//    static CyclicBarrier cyclicBarrier = new CyclicBarrier(3);

    public static void main(String[] args) {
        new Thread(new Runnable() {
            public void run() {
                try {
                    cyclicBarrier.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (BrokenBarrierException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName()+"打印1");
            }
        },"子线程1").start();
        try {
            cyclicBarrier.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (BrokenBarrierException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName()+"打印2");
    }
}
<file_sep>/**
 * 版权申明
 */
package step6;

import com.mj.currencyprogramming.step6.ForkJoinCounter;
import org.junit.Test;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.Future;

/**
 * @Title ForkJoinCounterTest.java
 * @Description ForkJoinCounter单元测试类
 * @Date 2015/11/24 16:56
 * @Author jiayi <EMAIL>
 * @Version 2.0
 */
public class ForkJoinCounterTest{
    private ForkJoinPool forkJoinPool = new ForkJoinPool();
    private ForkJoinCounter forkJoinCounter = new ForkJoinCounter(1, 1000000000);

    @Test
    public void testForkJoinCounter(){
        long startTime = System.currentTimeMillis();
        Future<Long> result = forkJoinPool.submit(forkJoinCounter);
        try {
            System.out.println(result.get());
            System.out.println("多线程耗时："+(System.currentTimeMillis()-startTime));
            if (forkJoinCounter.isCompletedAbnormally()){
                System.out.println(forkJoinCounter.getException());
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }

    @Test
    public void testSiganlThreadCounter(){
        long startTime = System.currentTimeMillis();
        long sum = 0;
        for (long i=0; i<=1000000000; i++){
            sum += i;
        }
        System.out.println(sum);
        System.out.println("单线程耗时："+(System.currentTimeMillis()-startTime));
    }
}
<file_sep>/**
 * 版权申明
 */
package com.mj.currencyprogramming.step4;

/**
 * @Title Interrupted
 * @Description Interrupted线程中断
 * @Date 2015/11/17 9:19
 * @Author jiayi <EMAIL>
 * @Version 2.0
 */
public class Interrupted {
    /**
     * ==============================================================
     *  线程中断，如果线程抛出了InterruptedException，会清除中断标识
     *  位。
     * ==============================================================
     */

    static class SleepRunnable implements Runnable{

        public void run() {
            while (true){
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    static class BusyRunnable implements Runnable{

        public void run() {
            while (true){

            }
        }
    }

    public static void main(String[] args) throws InterruptedException {
        Thread sleepThread = new Thread(new SleepRunnable(), "SleepThread");
        sleepThread.setDaemon(true);
        Thread busyThread = new Thread(new BusyRunnable(), "BusyThread");
        busyThread.setDaemon(true);
        sleepThread.start();
        busyThread.start();
        Thread.sleep(5000);
        sleepThread.interrupt();
        busyThread.interrupt();
        System.out.println("sleepThread.isInterrupted:"+sleepThread.isInterrupted());
        System.out.println("busyThread.isInterrupted:"+busyThread.isInterrupted());
        Thread.sleep(1000);
    }
}
<file_sep>/**
 * 版权申明
 */
package step5;

import com.mj.currencyprogramming.step5.MonopolizeLock;
import org.junit.Test;

/**
 * @Title MonopolizeLockTest.java
 * @Description MonopolizeLock测试类
 * @Date 2015/11/24 14:16
 * @Author jiayi <EMAIL>
 * @Version 2.0
 */
public class MonopolizeLockTest {
    /**
     * 重入锁和不可重入锁的区别.
     * synchronized和ReentrantLock都是可重入锁.
     */

    private MonopolizeLock monopolizeLock = new MonopolizeLock();

    @Test
    public void testMonopolizeLock(){
        new Thread(new Runnable() {
            public void run() {
                method1();
            }
        }, "T0").start();
    }

    private void method0(){
        monopolizeLock.lock();
        try{
            System.out.println(Thread.currentThread().getName()+"获得了锁");
        }finally {
            monopolizeLock.unlock();
        }
    }

    private void method1(){
        monopolizeLock.lock();
        try{
            System.out.println(Thread.currentThread().getName()+"获得了锁");
            method0();
        }finally {
            monopolizeLock.unlock();
        }
    }

}
<file_sep>/**
 * 版权申明
 */
package com.mj.currencyprogramming.step5;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @Title ConditionUse.java
 * @Description ConditionUse,Condition对象的使用
 * @Date 2015/11/24 10:19
 * @Author jiayi <EMAIL>
 * @Version 2.0
 */
public class ConditionUse {
    /**
     * ==================================================================
     *  Condition类似于Object对象上面隐式的监控器（wait、notify等方法）
     *  它与Lock实现对象绑定，也即是依赖于Lock实现对象
     * ==================================================================
     */
    private Lock lock = new ReentrantLock();
    private Condition condition = lock.newCondition();

    public void conditionWait(){
        lock.lock();
        try{
            System.out.println(Thread.currentThread().getName()+"获得锁");
            System.out.println(">>>>>执行任务1");
            System.out.println("被挂起...");
            condition.await();
            System.out.println(">>>>>执行任务2");
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    public void conditionNotify(){
        lock.lock();
        try{
            condition.signal();
            System.out.println(Thread.currentThread().getName()+"唤醒被挂起对象");
        }finally {
            lock.unlock();
        }
    }

    public static void main(String[] args) throws InterruptedException {
        final ConditionUse conditionUse = new ConditionUse();
        new Thread(new Runnable() {
            public void run() {
                conditionUse.conditionWait();
            }
        }, "Thread0").start();
        Thread.sleep(3000);
        new Thread(new Runnable() {
            public void run() {
                conditionUse.conditionNotify();
            }
        }, "Thread1").start();
        Thread.sleep(3000);
    }
}
<file_sep>/**
 * 版权申明
 */
package step8;

import com.mj.currencyprogramming.step8.UseJoinCompareCountDownLatch;
import org.junit.Test;

/**
 * @Title UseJoinCompareCountDownLatchTest.java
 * @Description UseJoinCompareCountDownLatch测试类
 * @Date 2015/11/25 11:01
 * @Author jiayi <EMAIL>
 * @Version 2.0
 */
public class UseJoinCompareCountDownLatchTest {
    @Test
    public void useJoin() throws InterruptedException {
        UseJoinCompareCountDownLatch.useJoin();
    }

    @Test
    public void useCountDownLatch() throws InterruptedException {
        UseJoinCompareCountDownLatch.useCountDownLatch();
    }
}
<file_sep>/**
 * 版权申明
 */
package com.mj.currencyprogramming.step7;

import java.util.concurrent.atomic.AtomicIntegerArray;

/**
 * @Title AtomicIntegerArrayUse.java
 * @Description AtomicIntegerArray简单使用
 * @Date 2015/11/25 10:07
 * @Author jiayi <EMAIL>
 * @Version 2.0
 */
public class AtomicIntegerArrayUse {
    /**
     * ========================================================================
     *  使用AtomicIntegerArray操作数组时，原数组值不变
     *  AtomicLongArray:原子更新长整形数组里的元素
     *  AtomicReferenceArray:原子更新引用数组里的元素
     *  底层都是使用Unsafe去做CAS
     * ========================================================================
     */
    static int[] data = new int[]{1,2,3,4};
    static AtomicIntegerArray atomicIntegerArray = new AtomicIntegerArray(data);

    public static void main(String[] args) throws InterruptedException {
        for (int i=0; i<2; i++){
            new Thread(new Runnable() {
                public void run() {
                    System.out.println(Thread.currentThread().getName()+">>>>>>>>>>>>AtomicIntegerArray.getAndAdd(2,10):"
                            +atomicIntegerArray.getAndAdd(2,10)+",AtomicIntegerArray.get(2):"+atomicIntegerArray.get(2));
                    System.out.println("data[2]:"+data[2]);
                }
            },"线程"+i).start();
        }
        Thread.currentThread().join();
    }
}
<file_sep>/**
 * 版权申明
 */
package com.mj.currencyprogramming.step1;

/**
 * @Title DeadLock.java
 * @Description 死锁
 * @Date 2015/11/13 11:20
 * @Author jiayi <EMAIL>
 * @Version 2.0
 */
public class DeadLock {
    private static Object a = new Object();
    private static Object b = new Object();

    public static void main(String[] args) throws InterruptedException {
        Thread t1 = new Thread(new Runnable() {
            public void run() {
                synchronized (a){
                    System.out.println(Thread.currentThread().getName()+"获得a资源");
                    try {
                        Thread.sleep(10*1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName()+"请求获得b资源...");
                    synchronized (b){
                        System.out.println(Thread.currentThread().getName()+"获得b资源");
                        System.out.println(Thread.currentThread().getName()+"执行任务");
                    }
                }
            }
        });
        Thread t2 = new Thread(new Runnable() {
            public void run() {
                synchronized (b){
                    System.out.println(Thread.currentThread().getName()+"获得b资源");
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName()+"请求获得a资源...");
                    synchronized (a){
                        System.out.println(Thread.currentThread().getName()+"获得a资源");
                        System.out.println(Thread.currentThread().getName()+"执行任务");
                    }
                }
            }
        });
        t1.start();
        t2.start();

        Thread.sleep(600*1000);
    }
}
<file_sep>/**
 * 版权申明
 */
package com.mj.currencyprogramming.step8;

import java.util.Map;
import java.util.concurrent.*;

/**
 * @Title BankWaterService.java
 * @Description 银行流水计算
 * @Date 2015/11/25 11:26
 * @Author jiayi <EMAIL>
 * @Version 2.0
 */
public class BankWaterService implements Runnable {
    private CyclicBarrier cyclicBarrier = new CyclicBarrier(4, this);
    private Executor executor =  Executors.newFixedThreadPool(4);
    private ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(4,4,0, TimeUnit.SECONDS,new ArrayBlockingQueue<Runnable>(10));
    private ConcurrentHashMap<String,Integer> map = new ConcurrentHashMap<String, Integer>();

    public void count(){
        for (int i=0; i<4; i++){
            final int finalI = i;
            executor.execute(new Runnable() {
                public void run() {
                    map.put(Thread.currentThread().getName(), finalI);
                    try {
                        cyclicBarrier.await();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    } catch (BrokenBarrierException e) {
                        e.printStackTrace();
                    }
                }
            });
        }
    }

    public void run() {
        int sum = 0;
        for (Map.Entry<String,Integer> entry:map.entrySet()){
            sum += entry.getValue();
        }
        map.put("sum",sum);
        System.out.println("sum:"+sum);
    }
}
<file_sep>/**
 * 版权申明
 */
package com.mj.currencyprogramming.step4;

import java.util.concurrent.*;

/**
 * @Title CountDownLatchTest2.java
 * @Description CountDownLatchTest2，业务场景2
 * @Date 2015/11/18 15:46
 * @Author jiayi <EMAIL>
 * @Version 2.0
 */
public class CountDownLatchTest2 {
    /**
     * =========================================================================
     *  CountDownLatch执行场景2：
     *      将可以一个大任务划为几个可以并发执行的小任务，并通过线程池进行处理
     *      当所有小任务执行完毕后，进行任务完成后处理。
     * =========================================================================
     */

    public static void main(String[] args) throws InterruptedException {
        int taskNum = 10;
        CountDownLatch doneSignal = new CountDownLatch(taskNum);
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(3, 3, 0, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(10),
                Executors.defaultThreadFactory());
        for (int i=0; i<taskNum; i++){
            threadPoolExecutor.execute(new TaskRunnable(doneSignal, i));
        }
        doneSignal.await();
        allTaskExecuteComplete();
        threadPoolExecutor.shutdown();
    }

    private static void allTaskExecuteComplete(){
        System.out.println("所有任务执行完毕.");
    }

    static class TaskRunnable implements Runnable{
        private final CountDownLatch doneSignal;
        private final int taskId;
        public TaskRunnable(CountDownLatch doneSignal, int taskId){
            this.doneSignal = doneSignal;
            this.taskId = taskId;
        }
        public void run() {
            try {
                doWork(taskId);
                doneSignal.countDown();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        private void doWork(int taskId) throws InterruptedException {
            System.out.println("线程"+taskId+" 执行了任务[id="+taskId+"]");
            Thread.sleep(3000);
        }
    }
}
<file_sep>/**
 * 版权申明
 */
package com.mj.currencyprogramming.step5;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @Title BoundedQueue.java
 * @Description BoundedQueue,使用Lock、Condition实现一个有界队列
 * @Date 2015/11/24 10:49
 * @Author jiayi <EMAIL>
 * @Version 2.0
 */
public class BoundedQueue {
    private Lock lock = new ReentrantLock();
    private Condition notFull = lock.newCondition();
    private Condition notEmpty = lock.newCondition();
    private Object[] bqueue;
    private int addIndex, removeIndex, count;

    public BoundedQueue(int size){
        bqueue = new Object[size];
    }

    public void add(Object obj){
        lock.lock();
        try{
            System.out.println(Thread.currentThread().getName()+"获得了资源锁");
            while (count == bqueue.length){
                System.out.println(Thread.currentThread().getName()+":队列已满，不能添加资源");
                notFull.await();
            }
            bqueue[addIndex] = obj;
            System.out.println(Thread.currentThread().getName()+":队列未满，添加资源["+obj+"]");
            if (++addIndex == bqueue.length){
                addIndex = 0;
            }
            ++count;
            notEmpty.signal();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    public Object remove(){
        lock.lock();
        try{
            System.out.println(Thread.currentThread().getName()+"获得了资源锁");
            while (count == 0){
                System.out.println(Thread.currentThread().getName()+":队列为空，不能消费资源");
                notEmpty.await();
            }
            Object obj = bqueue[removeIndex];
            System.out.println(Thread.currentThread().getName()+":队列不为空，消费资源["+obj+"]");
            if (++removeIndex == bqueue.length){
                removeIndex = 0;
            }
            --count;
            notFull.signal();
            return obj;
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
        return null;
    }

}
<file_sep>/**
 * 版权申明
 */
package com.mj.currencyprogramming.step4;

/**
 * @Title ShutdownThread.java
 * @Description ShutdownThread介绍两种终止线程的方法
 * @Date 2015/11/17 9:45
 * @Author jiayi <EMAIL>
 * @Version 2.0
 */
public class ShutdownThread {
    /**
     * ============================================================
     *  通过线程中断和设置标志位对线程停止，而不调用stop方法
     * ============================================================
     */

    static class DemoRunnable implements Runnable{
        private volatile boolean on = true;
        private long i;
        public void run() {
            while (on && !Thread.currentThread().isInterrupted()){
                i++;
            }
            System.out.println(Thread.currentThread().getName()+" count i:"+i);
        }

        public void cancel(){
            on = false;
        }
    }

    public static void main(String[] args) throws InterruptedException {
        DemoRunnable demoRunnable1 = new DemoRunnable();
        DemoRunnable demoRunnable2 = new DemoRunnable();
        Thread t1 = new Thread(demoRunnable1, "threadShutdownByInterrupt");
        Thread t2 = new Thread(demoRunnable2, "threadShutdownByFlag");
        t1.start();
        t2.start();
        Thread.sleep(3000);
        t1.interrupt();
        demoRunnable2.cancel();
    }
}
<file_sep>/**
 * 版权申明
 */
package com.mj.currencyprogramming.step8;

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

/**
 * @Title CyclicBarrierUse2
 * @Description CyclicBarrier简单使用
 * @Date 2015/11/25 11:15
 * @Author jiayi <EMAIL>
 * @Version 2.0
 */
public class CyclicBarrierUse2 {
    static CyclicBarrier cyclicBarrier = new CyclicBarrier(2,new RunnableA());

    public static void main(String[] args) {
        new Thread(new Runnable() {
            public void run() {
                try {
                    cyclicBarrier.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (BrokenBarrierException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName()+"执行了任务1");
            }
        },"子线程1").start();
        try {
            cyclicBarrier.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (BrokenBarrierException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName()+"执行了任务2");
    }
    static class RunnableA implements Runnable{
        public void run() {
            System.out.println(Thread.currentThread().getName()+"，这是优先线程，先执行.");
        }
    }
}
<file_sep>/**
 * 版权申明
 */
package com.mj.currencyprogramming.step7;

import java.util.concurrent.atomic.AtomicReference;

/**
 * @Title AtomicReferenceUse.java
 * @Description AtomicReference简单使用
 * @Date 2015/11/25 10:17
 * @Author jiayi <EMAIL>
 * @Version 2.0
 */
public class AtomicReferenceUse {
    /**
     * ======================================================================
     *  AtomicReference:原子更新引用类型
     *  AtomicReferenceFieldUpdater:原子更新引用类型的字段
     *  AtomicMarkableReference:原子更新带有标记位的引用类型
     * ======================================================================
     */

    static AtomicReference<User> atomicReference = new AtomicReference<User>();

    public static void main(String[] args) throws InterruptedException {
        final User initUser = new User("张三", 22);
        atomicReference.set(initUser);
        final User updateUser = new User("李四", 30);
        for (int i=0; i<2; i++){
            new Thread(new Runnable() {
                public void run() {
                    atomicReference.compareAndSet(initUser, updateUser);
                    System.out.println(Thread.currentThread().getName()+":"+atomicReference.get());
                }
            },"线程"+i).start();
        }
        Thread.currentThread().join();
    }

    static class User{
        private String name;
        private int age;

        public User(String name, int age) {
            this.name = name;
            this.age = age;
        }

        @Override
        public String toString() {
            return "User{" +
                    "name='" + name + '\'' +
                    ", age=" + age +
                    '}';
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public int getAge() {
            return age;
        }

        public void setAge(int age) {
            this.age = age;
        }
    }
}
<file_sep>/**
 * 版权申明
 */
package com.mj.currencyprogramming.step1;

/**
 * @Title CurrencyCompareSerial.java
 * @Description 并发和串行效率比较
 * @Date 2015/11/13 9:09
 * @Author jiayi <EMAIL>
 * @Version 2.0
 */
public class CurrencyCompareSerial {
    public static int a = 0;

    /**
     * 并发，多线程
     * @param counter
     * @throws InterruptedException
     */
    private void currency(final int counter) throws InterruptedException {
        long startTime = System.currentTimeMillis();
        Thread thread = new Thread(new Runnable() {
            public void run() {
                for (int i=0; i<counter; i++){
                    a += 3;
                }
            }
        });
        thread.start();
        int b = 0;
        for (int i=0; i<counter; i++){
            b--;
        }
        thread.join();
        System.out.println("并发\t\t"+counter+"\t\t"+(System.currentTimeMillis()-startTime)+"\t\t"+a+"\t\t"+b);
    }

    /**
     * 串行，单线程
     * @param counter
     */
    private void serial(int counter){
        long startTime = System.currentTimeMillis();
        int a = 0;
        for (int i=0; i<counter; i++){
            a += 3;
        }
        int b = 0;
        for (int i=0; i<counter; i++){
            b--;
        }
        System.out.println("串行\t\t"+counter+"\t\t"+(System.currentTimeMillis()-startTime)+"\t\t"+a+"\t\t"+b);
    }

    public static void main(String[] args) throws InterruptedException {
        System.out.println("模式\t\t数量\t\t耗时\t\ta值\t\tb值");
        CurrencyCompareSerial currencyCompareSerial = new CurrencyCompareSerial();
        currencyCompareSerial.currency(10000);
        currencyCompareSerial.serial(10000);
        System.out.println("===================================================================");
        currencyCompareSerial.currency(100000);
        currencyCompareSerial.serial(100000);
        System.out.println("===================================================================");
        currencyCompareSerial.currency(1000000);
        currencyCompareSerial.serial(1000000);
        System.out.println("===================================================================");
        currencyCompareSerial.currency(10000000);
        currencyCompareSerial.serial(10000000);
        System.out.println("===================================================================");
        currencyCompareSerial.currency(1000000000);
        currencyCompareSerial.serial(1000000000);
    }
}
<file_sep>/**
 * 版权申明
 */
package com.mj.currencyprogramming.step8;

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

/**
 * @Title CyclicBarrierUse3.java
 * @Description CyclicBarrier与CountDownLatch区别使用
 * @Date 2015/11/25 14:07
 * @Author jiayi <EMAIL>
 * @Version 2.0
 */
public class CyclicBarrierUse3 {
    /**
     * ===========================================================
     *  CountDownLatch的计数器只能使用一次，CyclicBarrier的计数器
     *  可以使用多次，通过reset重置。CyclicBarrier还提供了其他方法
     *  getNumberWaiting、isBroken等
     * ===========================================================
     */
    static CyclicBarrier cyclicBarrier = new CyclicBarrier(2);

    public static void main(String[] args) {
        Thread thread = new Thread(new Runnable() {
            public void run() {
                try {
                    cyclicBarrier.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (BrokenBarrierException e) {
                    e.printStackTrace();
                }
            }
        });
        thread.start();
        thread.interrupt();
        System.out.println("numberWaiting:"+cyclicBarrier.getNumberWaiting());
        try {
            cyclicBarrier.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (BrokenBarrierException e) {
            e.printStackTrace();
            System.out.println(cyclicBarrier.isBroken());
        }

    }
}
<file_sep>/**
 * 版权申明
 */
package com.mj.currencyprogramming.step4;

import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * @Title Deprecated.java
 * @Description 线程的暂停、恢复和停止
 * @Date 2015/11/17 9:30
 * @Author jiayi <EMAIL>
 * @Version 2.0
 */
public class Deprecated {
    /**
     * ==========================================================
     *  线程的暂停、恢复和停止，不推荐使用。
     *  原因：线程在上面操作时，不会释放已获得的锁，容易引起死锁.
     * ==========================================================
     */
    static class PrintRunnable implements Runnable{

        public void run() {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd hh:mm:ss");
            while (true){
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName()+" run at "+sdf.format(new Date()));
            }
        }
    }

    public static void main(String[] args) throws InterruptedException {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd hh:mm:ss");
        Thread printThread = new Thread(new PrintRunnable(), "printThread");
        printThread.setDaemon(true);
        printThread.start();
        Thread.sleep(3000);
        printThread.suspend();
        System.out.println("printThread suspend at "+sdf.format(new Date()));
        Thread.sleep(3000);
        printThread.resume();
        System.out.println("printThread resume at "+sdf.format(new Date()));
        Thread.sleep(3000);
        printThread.stop();
        System.out.println("printThread stop at "+sdf.format(new Date()));
        Thread.sleep(3000);
    }
}
<file_sep>/**
 * 版权申明
 */
package com.mj.currencyprogramming.step4.simplehttpserver;

/**
 * @Title ThreadPool.java
 * @Description ThreadPool,模拟的线程池
 * @Date 2015/11/18 17:26
 * @Author jiayi <EMAIL>
 * @Version 2.0
 */
public interface ThreadPool<Job extends Runnable> {
    /**
     * 执行一个job，该job应该实现Runnable接口
     * @param job 任务
     */
    void execute(Job job);

    /**
     * 关闭线程池
     */
    void shutdown();

    /**
     * 增加工作者线程，由工作者线程处理线程
     * @param num 增加的数量
     */
    void addWorkers(int num);

    /**
     * 减少工作者线程
     * @param num 减少的数量
     */
    void removeWorkers(int num);

    /**
     * 获取正在等待执行的任务数量
     * @return 正在等待执行的任务数量
     */
    int getJobSize();
}
<file_sep>/**
 * 版权申明
 */
package com.mj.currencyprogramming.step10;

import java.util.Map;
import java.util.concurrent.*;

/**
 * @Title FutrueTaskUse.java
 * @Description FutrueTaskUse
 * @Date 2015/11/25 17:36
 * @Author jiayi <EMAIL>
 * @Version 2.0
 */
public class FutrueTaskUse {
    static final Map<String,Future<String>> map = new ConcurrentHashMap<String, Future<String>>();

    public static void main(String[] args) {
        for (int i=0; i<2; i++){
            new Thread(new Runnable() {
                public void run() {
                    System.out.println(Thread.currentThread().getName()+":"+FutrueTaskUse.executeTask("Task001"));
                }
            },"线程"+i).start();
        }
    }

    public static String executeTask(final String taskName){
        while (true){
            Future<String> future = map.get(taskName);
            if (future == null){
                Callable<String> task = new Callable<String>() {
                    public String call() throws Exception {
                        return taskName;
                    }
                };
                FutureTask<String> futureTask = new FutureTask<String>(task);
                future = map.put(taskName, futureTask);
                if (future == null){
                    future = futureTask;
                    futureTask.run();
                }
            }
            try{
                Thread.sleep(1000);
                return future.get();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
        }
    }
}
<file_sep>/**
 * 版权申明
 */
package com.mj.currencyprogramming.step8;

import java.util.concurrent.CountDownLatch;

/**
 * @Title UseJoinCompareCountDownLatch.java
 * @Description UseJoinCompareCountDownLatch，使用join和CountDownLatch完成同样的功能
 * @Date 2015/11/25 10:55
 * @Author jiayi <EMAIL>
 * @Version 2.0
 */
public class UseJoinCompareCountDownLatch {
    public static void useJoin() throws InterruptedException {
        Thread t1 = new Thread(new Runnable() {
            public void run() {
                System.out.println(Thread.currentThread().getName()+"执行步骤1");
            }
        }, "t1");
        Thread t2 = new Thread(new Runnable() {
            public void run() {
                System.out.println(Thread.currentThread().getName()+"执行步骤2");
            }
        }, "t2");
        t1.start();
        t2.start();
        t1.join();
        t2.join();
        System.out.println("任务执行完毕.");
    }

    public static void useCountDownLatch() throws InterruptedException {
        final CountDownLatch countDownLatch = new CountDownLatch(2);
        Thread t1 = new Thread(new Runnable() {
            public void run() {
                System.out.println(Thread.currentThread().getName()+"执行步骤1");
                countDownLatch.countDown();
            }
        }, "t1");
        Thread t2 = new Thread(new Runnable() {
            public void run() {
                System.out.println(Thread.currentThread().getName()+"执行步骤2");
                countDownLatch.countDown();
            }
        }, "t2");
        t1.start();
        t2.start();
        countDownLatch.await();
        System.out.println("任务执行完毕.");
    }
}
<file_sep>/**
 * 版权申明
 */
package com.mj.currencyprogramming.step6;

import java.util.concurrent.RecursiveTask;

/**
 * @Title ForkJoinCounter.java
 * @Description ForkJoinCounter,使用Fork/Join框架
 * @Date 2015/11/24 16:48
 * @Author jiayi <EMAIL>
 * @Version 2.0
 */
public class ForkJoinCounter extends RecursiveTask<Long>{
    private long taskNeedCount = 1000000;
    private long start;
    private long end;

    public ForkJoinCounter(long start, long end){
        this.start = start;
        this.end = end;
    }

    @Override
    protected Long compute() {
        long sum = 0;
        boolean isCanCompute = (end-start) <= taskNeedCount;
        if (isCanCompute){
            for (long i=start; i<=end; i++){
                sum += i;
            }
        }else{
            long middle = (start+end)/2;
            ForkJoinCounter leftCounter = new ForkJoinCounter(start, middle);
            ForkJoinCounter rightCounter = new ForkJoinCounter(middle+1, end);
            leftCounter.fork();
            rightCounter.fork();
            long leftCounterResult = leftCounter.join();
            long rightCounterResult = rightCounter.join();
            sum = leftCounterResult + rightCounterResult;
        }
        return sum;
    }
}
