当前位置:首页 > Java技术 > Java马士兵高并发编程视频学习笔记(一)

Java马士兵高并发编程视频学习笔记(一)

2022年11月07日 21:05:02Java技术8

1.同一个资源,同步和非同步的方法可以同时调用

package com.dingyu;

public class Y {
    public synchronized void m1() {
        System.out.println(Thread.currentThread().getName() + " m1 begin---------");
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName() + " m1 end---------");
    }

    public void m2() {
        System.out.println(Thread.currentThread().getName() + " m2 begin---------");
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName() + " m2 end---------");
    }
    public static void main(String[] args) {
        Y t = new Y();
//        new Thread(()->t.m1(),"t1").start();
//        new Thread(()->t.m2(),"t2").start();
        new Thread(new Runnable() {
            
            @Override
            public void run() {
                t.m1();
                
            }
        },"t1").start();;
    new Thread(new Runnable() {
            
            @Override
            public void run() {
                t.m2();
                
            }
        },"t2").start();;
    }
}

 

Java马士兵高并发编程视频学习笔记(一) _ JavaClub全栈架构师技术笔记

 

可以看到t1先执行,如果不能同时调用那么t2是不能执行的,必须等t1结束,释放锁后才能调用,但这里t2确先执行了,所以是可以同时调用的。

2.对业务写代码进行加锁,对读代码不进行加锁,会产生脏读

  

package com.dingyu;

public class U {
    private String name;
    private double banlance;

    public synchronized void set(String name, double balance) {
        this.name = name;
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        this.banlance = balance;
    }

    public double getBalance() {
        return banlance;
    }

    public static void main(String[] args) {
        U u = new U();
        new Thread(() -> u.set("zhangsan", 500)).start();
        System.out.println(u.getBalance());
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(u.getBalance());
    }
}

Java马士兵高并发编程视频学习笔记(一) _ JavaClub全栈架构师技术笔记

3.同线程内一个同步方法可以去调用另一个同步方法(重入锁 还有一种重入锁就是子类调用父类的同步方法)

package com.dingyu;

public class I {
    public synchronized void m1() {
        System.out.println("m1 start");
        m2();
        System.out.println("m1 end");
    }

    private synchronized void m2() {
        System.out.println("m2 start");
        System.out.println("m2 end");
    }

    public static void main(String[] args) {
        I i = new I();
        new Thread(() -> i.m1()).start();
    }

}

Java马士兵高并发编程视频学习笔记(一) _ JavaClub全栈架构师技术笔记

4.模拟一个简单的死锁

package com.dingyu;

public class DeadLock {
    private Object o1 = new Object();
    private Object o2 = new Object();

    public void m1() {
        synchronized (o1) {
            try {
                Thread.sleep(10000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            
            synchronized (o2) {
                System.out.println("如果出现这句话表示没有死锁");
            }
        }
        
    }
    
    public void m2() {
        synchronized(o2) {
            
            synchronized (o1) {
                System.out.println("如果出现这句话表示没有死锁");
            }
            
        }
        
    }
    public static void main(String[] args) {
        DeadLock deadLock=new DeadLock();
        new Thread(()->deadLock.m1()).start();
        new Thread(()->deadLock.m2()).start();
    }
}

5.如果执行同步方法中出现异常,那么就会自动释放锁,如果不想释放锁,加上try catch

package com.dingyu;

public class ReleaseLock {
    private int count = 0;
    private int i = 0;

    public synchronized void m1() {
        while (true) {
            System.out.println(Thread.currentThread().getName() + " " + count++);
            if (count % 10 == 0)
                i = 1 / 0;
        }
    }

    public static void main(String[] args) {
        ReleaseLock releaseLock = new ReleaseLock();
        new Thread(() -> releaseLock.m1(), "t1").start();
        new Thread(() -> releaseLock.m1(), "t2").start();
    }
}

Java马士兵高并发编程视频学习笔记(一) _ JavaClub全栈架构师技术笔记

 6.volatile关键字(无锁同步)

volatile关键字 每个线程都有自己的一小块内存,执行的时候会把变量copy过来,修改了后在写回对象,

执行m1方法的线程把 running读到内存里,与此同时主线程也把running读到内存,并进行修改,写回对象为false

但是执行m1的线程里的内存一直都是true啊(因为太忙了没空去刷新)所以会形成死循环,

volatile就是当running改了之后 *立马去通知其他线程,你们记得去主存刷新一下,一刷新,running为false,退出while循环。

package com.dingyu;
/**
 * volatile关键字   每个线程都有自己的一小块内存,执行的时候会把变量copy过来,修改了后在写回对象,
 * 执行m1方法的线程把 running读到内存里,与此同时主线程也把running读到内存,并进行修改,写回对象为false
 * 但是执行m1的线程里的内存一直都是true啊(因为太忙了没空去刷新)所以会形成死循环,volatile就是当running改了之后
 * 立马去通知其他线程,你们记得去主存刷新一下,一刷新,running为false,退出while循环。
 * @author dingyu
 *
 */
public class VolatileDemo {
    private volatile boolean running = true;

    public void m1() {
        System.out.println("m1 start");
        while (running) {
            
        }
        System.out.println("m1 end");
    }

    public static void main(String[] args) {
        VolatileDemo volatileDemo = new VolatileDemo();
        new Thread(() -> volatileDemo.m1()).start();
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        volatileDemo.running = false;

    }
}

7.voliatile 不能保证原子性 不能替换synchronized

package com.dingyu;

/**
 * voliatile 不能保证原子性 不能替换synchronized
 * 
 * @author dingyu
 *
 */
public class VolatileDemo02 {
    public volatile int count = 0;

    public void m1() {
        for (int i = 0; i <= 10000; i++)
            count++;
    }

    public static void main(String[] args) {
        VolatileDemo02 volatileDemo02 = new VolatileDemo02();
        for (int i = 0; i < 3; i++) {
            new Thread(() -> volatileDemo02.m1()).start();
        }
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(volatileDemo02.count);
    }
}

Java马士兵高并发编程视频学习笔记(一) _ JavaClub全栈架构师技术笔记

 8.多个原子类的方法之间不具备原子性

package com.dingyu;

import java.util.concurrent.atomic.AtomicInteger;

/**
 * 原子类 具有原子性,但两个原子类的方法之间不具备原子性
 * 
 * @author dingyu
 *
 */
public class AtomicDemo {
    private AtomicInteger count = new AtomicInteger();

    public void m1() {
        for (int i = 0; i < 100; i++) {            
            count.incrementAndGet();
            //两个原子类的方法之间不具备原子性
            count.incrementAndGet();
        
        }
    }
}

9.原子类的不具备可见性

package com.dingyu;

import java.util.concurrent.atomic.AtomicBoolean;

public class AtomicDemo02 {
    public AtomicBoolean running = new AtomicBoolean(true);

    public void m1() {
        while (running.get()) {

        }
    }

    public static void main(String[] args) {
        AtomicDemo02 demo02 = new AtomicDemo02();
        new Thread(()->demo02.m1()).start();
        demo02.running.set(false);
    }
}

10.锁是锁在堆内存的那个对象上,而不是引用

package com.dingyu;

/**
 * 锁是锁在堆内存的那个对象上,而不是引用
 * 
 * @author dingyu
 *
 */
public class ChangeReference {
    public Object o = new Object();

    public void m1() {
        //锁o
        synchronized (o) {
            while (true) {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName());
            }
        }
    }

    public static void main(String[] args) {
        ChangeReference changeReference = new ChangeReference();
        new Thread(() -> changeReference.m1(), "t1").start();//启动一个线程 叫t1
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        changeReference.o = new Object();//引用变了
        new Thread(() -> changeReference.m1(),"t2").start();//启动线程 t2
    }
}

 

Java马士兵高并发编程视频学习笔记(一) _ JavaClub全栈架构师技术笔记

 11.不要锁字符串常量

package com.dingyu;
/**
 * 不要锁字符串常量
 * @author dingyu
 *
 */
public class SynchronizedString {
    private String s1 = "hello";
    private String s2 = "hello";

    public void m1() {
        synchronized (s1) {
            while(true) {}
        }
    }

    public void m2() {
        synchronized (s2) {
            System.out.println("m2 start");
        }
    }

    public static void main(String[] args) {
        SynchronizedString synchronizedString = new SynchronizedString();
        new Thread(()->synchronizedString.m1()).start();
        new Thread(()->synchronizedString.m2()).start();
    }
}

12.wait 让线程暂停,释放锁, notify 唤醒线程,不释放锁

package com.dingyu2;

/**
 * wait 让线程暂停,释放锁, notify 唤醒线程,不释放锁
 * 
 * @author dingyu
 *
 */
public class WaitAndNotyifyDemo {
    private volatile int count = 0;
    private Object lock = new Object();

    public void m1() {
        synchronized (lock) {
            System.out.println("m1 start");
            for (int i = 0; i < 10; i++) {
                count++;
                System.out.println(count);
                if (count == 5) {
                    lock.notify();
                    try {
                        lock.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }

        }
    }

    public void m2() {
        synchronized (lock) {
            System.out.println("m2 start");
            if (count != 5) {
                try {
                    System.out.println("m2 在等着 但把锁释放了");
                    lock.wait();                    
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println("m2 end");
            lock.notify();
        }
    }

    public static void main(String[] args) {
        WaitAndNotyifyDemo waitAndNotyifyDemo = new WaitAndNotyifyDemo();
        new Thread(() -> waitAndNotyifyDemo.m2()).start();
        new Thread(() -> waitAndNotyifyDemo.m1()).start();
    }
}

 

作者:DingYu
来源链接:https://www.cnblogs.com/dddyyy/p/9965836.html

版权声明:
1、JavaClub(https://www.javaclub.cn)以学习交流为目的,由作者投稿、网友推荐和小编整理收藏优秀的IT技术及相关内容,包括但不限于文字、图片、音频、视频、软件、程序等,其均来自互联网,本站不享有版权,版权归原作者所有。

2、本站提供的内容仅用于个人学习、研究或欣赏,以及其他非商业性或非盈利性用途,但同时应遵守著作权法及其他相关法律的规定,不得侵犯相关权利人及本网站的合法权利。
3、本网站内容原作者如不愿意在本网站刊登内容,请及时通知本站(javaclubcn@163.com),我们将第一时间核实后及时予以删除。


本文链接:https://www.javaclub.cn/java/68394.html

分享给朋友:

“Java马士兵高并发编程视频学习笔记(一)” 的相关文章

java高级工程师面试题:如何设计一个高并发系统?

java高级工程师面试题:如何设计一个高并发系统?

面试题 如何设计一个高并发系统? 考点分析 说实话,如果面试官问你这个题目,那么你必须要使出全身吃奶劲了。为啥?因为你没看到现在很多公司招聘的 JD 里都是说啥,有高并发就经验者优先。 如果你确实有真才实学,在互联网公司里干过高并...

高并发秒杀系统API之SSM集成swagger与AdminLTE

高并发秒杀系统API之SSM集成swagger与AdminLTE

初衷与整理描述 Java高并发秒杀系统API是来源于网上教程的一个Java项目,慕课网地址:https://www.imooc.com/learn/587。 也是我接触Java的第一个项目。本来是一枚c#码农,公司计划部分业务转java,于是我利用业务时间自学Java才有了本文,...

java高并发处理

java高并发处理

      在java web项目开发者,最难解决的是高并发问题,我为搞并发解决方案,想出了一个解决方案。      a.应用层面:读写分离、缓存、队列、集群、令牌、系统拆分...

高并发下java项目遇到的各种坑--概述篇(一)

      最近在做一个跨境电商的项目,主要是做跨境电商的企业做清关服务,将跨境电商企业订单信息生成清关报文推动海关,推送物流公司并获取物流信息,将海关回执和物流信息分别推送给电商企业和仓库系统等功能。此文章是为了记录在整个技术选型,服务器搭建部署中...

Java内存模型JMM 高并发原子性可见性有序性简介 多线程中篇(十)

Java内存模型JMM 高并发原子性可见性有序性简介 多线程中篇(十)

不得不看的JMM介绍,JMM不同于java运行时内存区域划分,本文从区域划分拓展到JMM,多线程必备的知识点,并且从原子性可见性有序性三个角度深入的分析了JMM的在这几个点涉及的部分 JVM运行时内存结构回顾 在JVM相关的介绍中,有说到JAVA运行时的...

《实战Java高并发程序设计》读书笔记一

《实战Java高并发程序设计》读书笔记一

第一章 走入并行世界 1、基本概念 同步:同步方法一旦开始,调用者必须等到方法调用返回后,才能继续后续操作 异步:一旦开始,方法调用就会立即返回,调用就可以继续后续操作 并发:表示两个或者多个任务一起执行,偏重于任务交替执行,而多个任务之间...

Java:并发不易,先学会用

Java:并发不易,先学会用

我从事Java编程已经11年了,绝对是个老兵;但对于Java并发编程,我只能算是个新兵蛋子。我说这话估计要遭到某些高手的冷嘲热讽,但我并不感到害怕。 因为我知道,每年都会有很多很多的新人要加入Java编程的大军,他们对“并发”编程中遇到的问题也会有...

Java挑战高并发(4):守护线程与线程阻塞的四种情况

守护线程   Java中有两类线程:User Thread(用户线程)、Daemon Thread(守护线程) 用户线程即运行在前台的线程,而守护线程是运行在后台的线程。 守护线程作用是为其他前台线程的运行提供便利服务,而且仅在普...

详细介绍:多线程高并发

高并发与多线程的关系与区别 liuhuiteng 2019-03-09 21:30:41 13357 收藏 80 分类专栏: Java进阶 文章标签: 高并发 多线程 高并发指标 高并发解决方案 一、什么是高并发 高并发(High Concurre...

关于java并发,实际开发中的体会

1:java并发的分类,在实际开发中我一般讲java并发分为2个大类 1)业务并发,也叫程序并发,比如同时打开两个相同的网页.然后同时点了2个相同的按钮.(也就是java中的多线程) 2)数据并发,数据库中某个表中的某条记录,被多个程序同时使用.其中给一个程序对数据进...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。