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

java并发编程实战wwj———————-第一阶段————–27-28-29-30代码:chapter9sleep:是Threa的方法,sleep不释放锁,sleep不用synchronized,不需要被唤醒。wait:所有对象的方法,wait释放锁,用synchronized,要被唤醒。如何使用这个案例:切换m1和m2方法。packagechapter9;importjava.util.stream.Stream;/************…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用

代码:chapter9

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

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

wait:所有对象的方法,wait释放锁java并发编程实战wwj----------------------第一阶段--------------27-28-29-30

用synchronized,要被唤醒。

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

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

chapter9


package one.chapter9;

import java.util.stream.Stream;


public class DifferenceOfWaitAndSleep {

    private final static Object LOCK = new Object(); // 定义锁一定要定义final类型的

    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。

java并发编程实战wwj----------------------第一阶段--------------27-28-29-30线程的数量的优化图,多了上下文就多了会有开销的。

卡了看看是不是线程太多了。

jdk8的::https://blog.csdn.net/csmans/article/details/82256690

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

代码:

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

package one.chapter9;

import java.util.*;

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);
                });
        // 在这里去通体的join
        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();// 为什么remove
                // first?删掉的可能是自己也肯能是别人只要删掉就可以了 其实
                CONTROLS.notifyAll();
            }
        }, name);
    }

    private static class Control {
    }
}

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

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

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

代码chapter10

代码:

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

第一步:写一个接口

定义显示锁:


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();//获得被阻塞的线程的个数

}

先看下最终的代码

package one.chapter10;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Optional;

public class BooleanLock implements Lock {

    //The initValue is true indicated the lock have be get.
    //The initValue is false indicated the lock is free (other thread can get this.)
    private boolean initValue;

    // 被阻塞的线程
    private Collection<Thread> blockedThreadCollection = new ArrayList<>();

    private Thread currentThread;//为什么第一这个变量,谁加的锁只能由谁去释放的。

    public BooleanLock() {
        this.initValue = false;
    }

    @Override
    public synchronized void lock() throws InterruptedException {
        while (initValue) {//true就是我不能抢到锁了就得等着
            if(!blockedThreadCollection.contains(Thread.currentThread())){
                blockedThreadCollection.add(Thread.currentThread());
            }
            this.wait();// 就在lock上wait
        }
        blockedThreadCollection.remove(Thread.currentThread());
        this.initValue = true;
        this.currentThread = Thread.currentThread();//设置lock是当前的线程虽然抢锁失败了
    }

    @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();
        }
    }

       @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");
            if(!blockedThreadCollection.contains(Thread.currentThread())){
                blockedThreadCollection.add(Thread.currentThread());
            }
            this.wait(mills);
            hasRemaining = endTime - System.currentTimeMillis();
        }
        blockedThreadCollection.remove(Thread.currentThread());
        this.initValue = true;
        this.currentThread = Thread.currentThread();
    }

    /**
     * 注意这个要考线程安全 其他的线程可以在其他的方法操作这个集合
     * @return
     */
    @Override
    public Collection<Thread> getBlockedThread() {
        return Collections.unmodifiableCollection(blockedThreadCollection);
    }

    @Override
    public int getBlockedSize() {
        return blockedThreadCollection.size();
    }
}

———-29——————————–

第一个一个bug:

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

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

  @Override
    public synchronized void lock() throws InterruptedException {
        while (initValue) {//true就是我不能抢到锁了就得等着
            if(!blockedThreadCollection.contains(Thread.currentThread())){
                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;


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可以打断但是不能中断进入java并发编程实战wwj----------------------第一阶段--------------27-28-29-30

t2是一直block住的。我们不能让t2释放回来。做线程的其他的事情。

java并发编程实战wwj----------------------第一阶段--------------27-28-29-30我们要解决这个问题。

    @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");
            if(!blockedThreadCollection.contains(Thread.currentThread())){
                blockedThreadCollection.add(Thread.currentThread());
            }
            this.wait(mills);
            hasRemaining = endTime - System.currentTimeMillis();
        }
        blockedThreadCollection.remove(Thread.currentThread());
        this.initValue = true;
        this.currentThread = Thread.currentThread();
    }

——————————-30——————————-

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/188765.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 2021年十大开源web应用防火墙

    2021年十大开源web应用防火墙开源web应用防火墙是网络安全的重要部分,Cloudflare认为:十年后数字经济的网络安全基础设施会像水过滤系统一样普及,而这个过滤系统的核心就是waf。对于服务器来说,部署WEB应用防火墙十分重要,笔者经过大量搜索,并结合市场热度,整理出2021年十大开源web应用防火墙。1、OpenRestyOpenResty是由中国人章亦春发起,把nginx和各种三方模块的一个打包而成的软件平台,核心就是nginx+lua脚本语言。主要是因为nginx是C语言编写,修改很复杂,而lua语言则简单得多,国内很多

    2022年6月2日
    193
  • expandablelistview详解[通俗易懂]

    expandablelistview详解[通俗易懂]我在项目中使用到expandablelistview,然后我就在网上找了很多关于expandablelistview的文章,那么这里,将一些对去进行总结一些,并将自己踩过的坑填上。expandablelistview就是类似QQ分组,点击分类,显示其各个详细的分类信息。下面是一些效果图这样是完成了有父标题,和子标题,实现了分组,接下来看看如何布局的。

    2022年6月18日
    29
  • extremedb是开源的吗_最简单的数据库开发软件

    extremedb是开源的吗_最简单的数据库开发软件最近我接触了嵌入式数据库eXtremeDB,由于这方面资料很少,网上的参考资料都大同小异,只靠着软件本身提供的参考文档进行开发,所以刚开始开发有些困难。故将基本的用法整理一下。关于eXtremeDB的特性,这里就不阐述了,直接从开发开始。下面以简单的模板为例进行阐述。1.构建.mco文件打开记事本,然后另存为XX.mco后缀文件。.mco文件里面需要定义数据库所需的字段类型,名称等,…

    2022年10月14日
    3
  • Android应用开发揭秘

    Android应用开发揭秘《Android应用开发揭秘》                                              ///////http://www.iteye.com/wiki/hzbook/2249-Android  书名:Android应用开发揭秘作者:杨丰盛出版社:机械工业出版社ISBN:9787111291954出版日期:2010年3月(1版2次)…

    2022年4月28日
    42
  • 排序 专题讨论

    排序 专题讨论

    2021年10月6日
    36
  • 2019年常见的Linux面试题及答案解析,哪些你还不会?

    2019年常见的Linux面试题及答案解析,哪些你还不会?Linux面试题1、绝对路径用什么符号表示?当前目录、上层目录用什么表示?主目录用什么表示?切换目录用什么命令?2、怎么查看当前进程?怎么执行退出?怎么查看当前路径?3、怎么清屏?怎么退出当前命令?怎么执行睡眠?怎么查看当前用户id?查看指定帮助用什么命令?4、Ls命令执行什么功能?可以带哪些参数,有什么区别?5、建立软链接(快捷方式),以及硬链接的命令。6、目录创…

    2022年5月31日
    34

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号