java并发编程实战wwj----------------------第一阶段--------------27-28-29-30

主宰稳场 提交于 2019-12-12 02:30:07

代码:chapter9

sleep:是Threa的方法,sleep不释放锁,sleep不用synchronized,不需要被唤醒。

wait:所有对象的方法,wait释放锁,用synchronized,要被唤醒。

如何使用这个案例:切换m1和m2方法。


package chapter9;

import java.util.stream.Stream;

/***************************************
 * @author:Alex Wang
 * @Date:2017/2/20 QQ:532500648
 * QQ交流群:286081824
 ***************************************/
public class DifferenceOfWaitAndSleep {

    private final static Object LOCK = new Object();

    public static void main(String[] args) {
        Stream.of("T1", "T2").forEach(name ->
                new Thread(name) {
                    @Override
                    public void run() {
                        m1();
                    }
                }.start()
        );
    }

    public static void m1() {
        synchronized (LOCK) {
            try {
                System.out.println("The Thread " + Thread.currentThread().getName() + " enter.");
                Thread.sleep(20000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }


    public static void m2() {
        synchronized (LOCK) {
            try {
                System.out.println("The Thread " + Thread.currentThread().getName() + " enter.");
                LOCK.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

---------------------------------------------------27-----------sleep和wait的区别-------------------------------------------------------

先start之后才可以join。先设置守护线程才可以start。

---

问题:10000台机器如何用100个线程采集,线程多了会有问题,上下文切换。

代码:

package chapter9;

import java.util.*;

/***************************************
 * @author:Alex Wang
 * @Date:2017/2/20 QQ:532500648
 * QQ交流群:286081824
 ***************************************/
public class CaptureService {

    final static private LinkedList<Control> CONTROLS = new LinkedList<>();
    private final static int MAX_WORKER = 5;

    public static void main(String[] args) {

        List<Thread> worker = new ArrayList<>();
        Arrays.asList("M1", "M2", "M3", "M4", "M5", "M6", "M7", "M8", "M9", "M10").stream()
                .map(CaptureService::createCaptureThread)
                .forEach(t -> {
                    t.start();
                    worker.add(t);
                });

        worker.stream().forEach(t -> {
            try {
                t.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        Optional.of("All of capture work finished").ifPresent(System.out::println);
    }


    private static Thread createCaptureThread(String name) {
        return new Thread(() -> {
            Optional.of("The worker [" + Thread.currentThread().getName() + "] BEGIN capture data.")
                    .ifPresent(System.out::println);
            synchronized (CONTROLS) {
                while (CONTROLS.size() > MAX_WORKER) {//要是有5个就乖乖等着就可以
                    try {
                        CONTROLS.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }

                CONTROLS.addLast(new Control());//跳出while就说明可以跑了加入跑的队列  对公共数据操作要串行化保护的
            }


            Optional.of("The worker [" + Thread.currentThread().getName() + "] is working...")
                    .ifPresent(System.out::println);
            try {
                Thread.sleep(10000);
            } catch (InterruptedException e) {//采集时间是10S  并行去执行任务

                e.printStackTrace();
            }

            synchronized (CONTROLS) {//工作完了我吧自己移除工作队列
                Optional.of("The worker [" + Thread.currentThread().getName() + "] END capture data.")
                        .ifPresent(System.out::println);
                CONTROLS.removeFirst();
                CONTROLS.notifyAll();
            }
        }, name);
    }

    private static class Control {
    }
}

对公共数据的操作要设置同步的保护的,这是真理。

---------------------------------------------------28----------控制并发---------------------------------------------------------------

自定义的锁解决synchronized的慢的问题:

代码:

定义显示锁:

/***************************************
 * @author:Alex Wang
 * @Date:2017/2/22 QQ:532500648
 * QQ交流群:286081824
 ***************************************/
public interface Lock {

    class TimeOutException extends Exception {
        public TimeOutException(String message) {//报错信息
            super(message);
        }
    }

    void lock() throws InterruptedException;//加锁

    void lock(long mills) throws InterruptedException, TimeOutException;//没有获取到锁就退出来了

    void unlock();//释放锁

    Collection<Thread> getBlockedThread();//获得被阻塞的线程

    int getBlockedSize();//获得被阻塞的线程的个数

}

---------------------------------------------------------29-------------------------------------------------------------------------------------

第一个一个bug:

t1加的锁只能t1去释放,其他的是不能去释放的。

  @Override
    public synchronized void lock() throws InterruptedException {
        while (initValue) {//true就是我不能抢到锁了就得等着
            blockedThreadCollection.add(Thread.currentThread());
            this.wait();
        }

        blockedThreadCollection.remove(Thread.currentThread());
        this.initValue = true;
        this.currentThread = Thread.currentThread();//Thread.currentThread()这个是获取到锁的线程
    }

    @Override
    public synchronized void unlock() {//这个synchronized锁的是BooleanLock的实例
        if (Thread.currentThread() == currentThread) {//是当前的线程才释放的
            this.initValue = false;
            Optional.of(Thread.currentThread().getName() + " release the lock monitor.")
                    .ifPresent(System.out::println);
            this.notifyAll();
        }
    }

第二个问题:synchronized不能打断的,导致等待时间过长,这个是synchronized的工作机制。

package chapter10;

/***************************************
 * @author:Alex Wang
 * @Date:2017/2/22 QQ:532500648
 * QQ交流群:286081824
 ***************************************/
public class SynchronizedProblem {

    public static void main(String[] args) throws InterruptedException {

        new Thread() {
            @Override
            public void run() {
                SynchronizedProblem.run();
            }
        }.start();

        Thread.sleep(1000);

        Thread t2 = new Thread() {
            @Override
            public void run() {
//                /sdfsdfsd
                SynchronizedProblem.run();
                //sdfsdfsd
                System.out.println("继续做以下的事情t");
            }
        };
        t2.start();
        Thread.sleep(2000);
        t2.interrupt();
        System.out.println(t2.isInterrupted());
    }

    private synchronized static void run() {
        System.out.println(Thread.currentThread());
        while (true) {

        }
    }
}

t2可以打断但是不能中断进入

我们要解决这个问题。

 @Override
    public synchronized void lock(long mills) throws InterruptedException, TimeOutException {
        if (mills <= 0)
            lock();

        long hasRemaining = mills;//需要等的时间
        long endTime = System.currentTimeMillis() + mills;//到什么时间结束
        while (initValue) {//需要等待   醒了我就去抢锁,抢不到我就加时间  多次醒了请不到我就超时了 我直接抛出异常了
            if (hasRemaining <= 0)
                throw new TimeOutException("Time out");
            blockedThreadCollection.add(Thread.currentThread());
            this.wait(mills);
            hasRemaining = endTime - System.currentTimeMillis();
        }

        this.initValue = true;
        this.currentThread = Thread.currentThread();

-----------------------------------------------------------30-------------------------------------------------------------------------------

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!