程序员

九.线程的应用

2017-09-20  本文已影响0人  蜗牛1991

一.多线程概念与优点

二.创建线程方式

三.线程的生命周期

image.png

四 线程同步方式

public class SynchronizedTest {

        public static void main(String[] args) {
            Clerk clerk = new Clerk();
            Clerk clerk1 = new Clerk();
            Consumer con = new Consumer(clerk);
            Consumer con1 = new Consumer(clerk1);
            new Thread(con, "消费者 A").start();
            new Thread(con, "消费者 B").start();
            new Thread(con1, "消费者 C").start();
            new Thread(con1, "消费者 D").start();
        }
    }
// 店员
class Clerk {
    private //*static*// int product = 5;
    // 进货
    public  synchronized void get() { // 循环:0
        while (product > 5) {
            System.out.println("产品已满!");

            try {
                this.wait();
            } catch (InterruptedException e) {
            }
        }
        System.out.println(Thread.currentThread().getName() + " : " + product++);
        this.notifyAll();
    }

    // 卖货
    public synchronized void sale() {// product = 0, 循环: 0
        while (product <= 0) { //为了避免虚假唤醒,wait() 应该总是使用在 循环中
            System.out.println("缺货!");
           try {
                this.wait();// ----
            } catch (InterruptedException e) {
            }
        }
        System.out.println(Thread.currentThread().getName() + " : " + product--);
        this.notifyAll();
    }
}

// 生产者
class Productor implements Runnable {
    private Clerk clerk;
    public Productor(Clerk clerk) {
        this.clerk = clerk;
    }
    @Override
    public void run() {
        for (int i = 0; i < 5; i++) {
            clerk.get();
        }
    }
}
// 消费者
class Consumer implements Runnable {
    private Clerk clerk;

    public Consumer(Clerk clerk) {
        super();
        this.clerk = clerk;
    }

    @Override
    public void run() {
        for (int i = 0; i < 5; i++) {
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            clerk.sale();
        }
    }
//不加static结果
产品已满!
消费者 A : 5
消费者 B : 4
消费者 C : 5
消费者 D : 4
消费者 A : 3
消费者 C : 3
消费者 B : 2
消费者 D : 2
消费者 B : 1
消费者 C : 1
缺货!
缺货!
缺货!
缺货!
//加了static结果
消费者 B : 5
消费者 C : 4
消费者 A : 3
消费者 D : 2
消费者 A : 0
消费者 C : 1
缺货!
缺货!
缺货!
缺货!
 private Lock lock = new ReentrantLock();
//线程通信
 private Condition condition2 = lock.newCondition();
 public void loopA(int totalLoop) {
        lock.lock();
          ...
      lock.unLock();
}
class AlternateDemo {
    private Lock lock = new ReentrantLock();
    private Condition condition1 = lock.newCondition();
    private Condition condition2 = lock.newCondition();
    private int number = 1; //用于确定当前执行线程的标记

    public void loopA(int totalLoop) {
        lock.lock();
        try {
            //判断
            if (number != 1) {
                try {
                    condition1.await();
                } catch (InterruptedException e) {
                }
            }
            //打印
            for (int i = 1; i <= 1; i++) {
                System.out.println(Thread.currentThread().getName() + "\t" + i + "\t" + totalLoop);
            }
            //唤醒
            number = 2;
            condition2.signal();
        } finally {
            lock.unlock();
        }
    }

    public void loopB(int totalLoop) {
        lock.lock();
        try {
            //判断
            if (number != 2) {
                try {
                    condition2.await();
                } catch (InterruptedException e) {
                }
            }
            //打印
            for (int i = 1; i <= 1; i++) {
                System.out.println(Thread.currentThread().getName() + "\t" + i + "\t" + totalLoop);
            }
            //唤醒
            number = 1;
            condition1.signal();
        } finally {
            lock.unlock();
        }
    }
}
public class CountDownLatchTest {
    public static void main(String[] args) throws InterruptedException {
        CountDownLatch startSignal = new CountDownLatch(1);
        CountDownLatch doneSignal = new CountDownLatch(3);
        ExecutorService executorService = Executors.newFixedThreadPool(5);
        for (int i=0;i<3;i++){
           executorService.execute(new Worker(startSignal, doneSignal));
        }
        System.out.println("准备完毕");
        startSignal.countDown();
        System.out.println("开始执行");
        doneSignal.await();
        System.out.println("执行完毕");

    }
     static class Worker implements Runnable {
        private  static Integer count=1;
        private final CountDownLatch startSignal;
        private final CountDownLatch doneSignal;
        Worker(CountDownLatch startSignal, CountDownLatch doneSignal) {
            this.startSignal = startSignal;
            this.doneSignal = doneSignal;
        }
        public void run() {
            try {
                startSignal.await();
                doWork(count);
                count++;
                doneSignal.countDown();
            } catch (InterruptedException ex) {} // return;
        }

        void doWork(Integer count) {
            System.out.println(Thread.currentThread().getName()+"-"+count);
        }
    }
}
//结果
准备完毕
开始执行
pool-1-thread-1-1
pool-1-thread-2-2
pool-1-thread-3-1
执行完毕
public class CyclicBarrierTest {
    public static void main(String[] args) {
        int N = 4;
        CyclicBarrier barrier = new CyclicBarrier(N, new Runnable() {
            @Override
            public void run() {
                System.out.println("所有线程写入完毕,继续处理其他任务...");
            }
        });

        for (int i = 0; i < N; i++)
            new Writer(barrier).start();
        try {
            Thread.sleep(2500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("CyclicBarrier重用");

        for(int i=0;i<N;i++) {
            new Writer(barrier).start();
        }
    }

    static class Writer extends Thread {
        private CyclicBarrier cyclicBarrier;

        public Writer(CyclicBarrier cyclicBarrier) {
            this.cyclicBarrier = cyclicBarrier;
        }

        @Override
        public void run() {
            try {
                System.out.println("线程" + Thread.currentThread().getName() + "写入数据完毕,等待其他线程写入完毕");
                cyclicBarrier.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (BrokenBarrierException e) {
                e.printStackTrace();
            }

        }
    }
}
//结果
线程Thread-0写入数据完毕,等待其他线程写入完毕
线程Thread-1写入数据完毕,等待其他线程写入完毕
线程Thread-2写入数据完毕,等待其他线程写入完毕
线程Thread-3写入数据完毕,等待其他线程写入完毕
所有线程写入完毕,继续处理其他任务...
CyclicBarrier重用
线程Thread-4写入数据完毕,等待其他线程写入完毕
线程Thread-5写入数据完毕,等待其他线程写入完毕
线程Thread-6写入数据完毕,等待其他线程写入完毕
线程Thread-7写入数据完毕,等待其他线程写入完毕
所有线程写入完毕,继续处理其他任务...
public class SemaphoreTest {
    public static void main(String[] args) throws InterruptedException {
        ExecutorService executorService = Executors.newFixedThreadPool(6);
        ContentPool contentPool = new ContentPool();
        System.out.println("总剩余资源为6,每次只能允许4个线程获得资源,当线程资源释放时,其他线程才可以继续获得资源");
        for (int i = 0; i < 6; i++) {
            executorService.execute(new user(contentPool));
        }
    }
}

class ContentPool {
    private static final int MAX_AVAILABLE = 4;
    private static int count = 6;
    private final Semaphore available = new Semaphore(MAX_AVAILABLE, true);

    public Object getItem() throws InterruptedException {
        available.acquire();
        --count;
        System.out.println("占用一个资源,剩余资源为:" + count);
        return getNextAvailableItem();
    }

    public void putItem(Object x) {
        if (markAsUnused(x))
            available.release();
        ++count;
        System.out.println("释放一个资源,剩余资源为:" + count);
    }

    protected int[] items = {1, 2, 3, 4,5,6};
    protected boolean[] used = new boolean[MAX_AVAILABLE];

    synchronized Object getNextAvailableItem() {
        for (int i = 0; i < MAX_AVAILABLE; ++i) {
            if (!used[i]) {
                used[i] = true;
                return items[i];
            }
        }
        return null; // not reached
    }

    synchronized boolean markAsUnused(Object item) {
        for (int i = 0; i < MAX_AVAILABLE; ++i) {
            if (item == items[i]) {
                if (used[i]) {
                    used[i] = false;
                    return true;
                } else
                    return false;
            }
        }
        return false;
    }
}

class user implements Runnable {
    private ContentPool contentPool;
    private int count = (int) (Math.random() * 5+ 1);

    public user(ContentPool contentPool) {
        this.contentPool = contentPool;
    }

    @Override
    public void run() {
        try {
            Object item = contentPool.getItem();
            System.out.println(Thread.currentThread().getName()+"得到资源"+item);
            Thread.sleep(1000);
            contentPool.putItem(count);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
//结果
总剩余资源为6,每次只能允许4个线程获得资源,当线程资源释放时,其他线程才可以继续获得资源
占用一个资源,剩余资源为:5
pool-1-thread-2得到资源1
占用一个资源,剩余资源为:4
占用一个资源,剩余资源为:3
pool-1-thread-6得到资源2
pool-1-thread-1得到资源3
占用一个资源,剩余资源为:2
pool-1-thread-5得到资源4
释放一个资源,剩余资源为:3
占用一个资源,剩余资源为:2
pool-1-thread-3得到资源3
释放一个资源,剩余资源为:4
释放一个资源,剩余资源为:5
释放一个资源,剩余资源为:6
占用一个资源,剩余资源为:3
pool-1-thread-4得到资源1
释放一个资源,剩余资源为:5
释放一个资源,剩余资源为:6
上一篇下一篇

猜你喜欢

热点阅读