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


    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---------");
    }

    </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> m2() {
        System.out.println(Thread.currentThread().getName() </span>+ " m2 begin---------"<span style="color: #000000;">);
        </span><span style="color: #0000ff;">try</span><span style="color: #000000;"> {
            Thread.sleep(</span>5000<span style="color: #000000;">);
        } </span><span style="color: #0000ff;">catch</span><span style="color: #000000;"> (InterruptedException e) {
            </span><span style="color: #008000;">//</span><span style="color: #008000;"> TODO Auto-generated catch block</span>
    

    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
            </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> run() {
                t.m1();
                
            }
        },</span>"t1"<span style="color: #000000;">).start();;
    </span><span style="color: #0000ff;">new</span> Thread(<span style="color: #0000ff;">new</span><span style="color: #000000;"> Runnable() {
            
            @Override
            </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> run() {
                t.m2();
                
            }
        },</span>"t2"<span style="color: #000000;">).start();;
    }
    

    }

    复制代码

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

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

      

    复制代码
    package com.dingyu;
    

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

    </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">synchronized</span> <span style="color: #0000ff;">void</span> set(String name, <span style="color: #0000ff;">double</span><span style="color: #000000;"> balance) {
        </span><span style="color: #0000ff;">this</span>.name =<span style="color: #000000;"> name;
        </span><span style="color: #0000ff;">try</span><span style="color: #000000;"> {
            Thread.sleep(</span>5000<span style="color: #000000;">);
        } </span><span style="color: #0000ff;">catch</span><span style="color: #000000;"> (InterruptedException e) {
            e.printStackTrace();
        }
        </span><span style="color: #0000ff;">this</span>.banlance =<span style="color: #000000;"> balance;
    }
    
    </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">double</span><span style="color: #000000;"> getBalance() {
        </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> banlance;
    }
    
    </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> main(String[] args) {
        U u </span>= <span style="color: #0000ff;">new</span><span style="color: #000000;"> U();
        </span><span style="color: #0000ff;">new</span> Thread(() -&gt; u.set("zhangsan", 500<span style="color: #000000;">)).start();
        System.out.println(u.getBalance());
        </span><span style="color: #0000ff;">try</span><span style="color: #000000;"> {
            Thread.sleep(</span>5000<span style="color: #000000;">);
        } </span><span style="color: #0000ff;">catch</span><span style="color: #000000;"> (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(u.getBalance());
    }
    

    }

    复制代码

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

    复制代码
    package com.dingyu;
    

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

    </span><span style="color: #0000ff;">private</span> <span style="color: #0000ff;">synchronized</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> m2() {
        System.out.println(</span>"m2 start"<span style="color: #000000;">);
        System.out.println(</span>"m2 end"<span style="color: #000000;">);
    }
    
    </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> main(String[] args) {
        I i </span>= <span style="color: #0000ff;">new</span><span style="color: #000000;"> I();
        </span><span style="color: #0000ff;">new</span> Thread(() -&gt;<span style="color: #000000;"> i.m1()).start();
    }
    

    }

    复制代码

    4.模拟一个简单的死锁

    复制代码
    package com.dingyu;
    

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

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

    }

    复制代码

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

    复制代码
    package com.dingyu;
    

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

    </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">synchronized</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> m1() {
        </span><span style="color: #0000ff;">while</span> (<span style="color: #0000ff;">true</span><span style="color: #000000;">) {
            System.out.println(Thread.currentThread().getName() </span>+ " " + count++<span style="color: #000000;">);
            </span><span style="color: #0000ff;">if</span> (count % 10 == 0<span style="color: #000000;">)
                i </span>= 1 / 0<span style="color: #000000;">;
        }
    }
    
    </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> main(String[] args) {
        ReleaseLock releaseLock </span>= <span style="color: #0000ff;">new</span><span style="color: #000000;"> ReleaseLock();
        </span><span style="color: #0000ff;">new</span> Thread(() -&gt; releaseLock.m1(), "t1"<span style="color: #000000;">).start();
        </span><span style="color: #0000ff;">new</span> Thread(() -&gt; releaseLock.m1(), "t2"<span style="color: #000000;">).start();
    }
    

    }

    复制代码

     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;
    
    </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> m1() {
        System.out.println(</span>"m1 start"<span style="color: #000000;">);
        </span><span style="color: #0000ff;">while</span><span style="color: #000000;"> (running) {
            
        }
        System.out.println(</span>"m1 end"<span style="color: #000000;">);
    }
    
    </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> main(String[] args) {
        VolatileDemo volatileDemo </span>= <span style="color: #0000ff;">new</span><span style="color: #000000;"> VolatileDemo();
        </span><span style="color: #0000ff;">new</span> Thread(() -&gt;<span style="color: #000000;"> volatileDemo.m1()).start();
        </span><span style="color: #0000ff;">try</span><span style="color: #000000;"> {
            Thread.sleep(</span>1000<span style="color: #000000;">);
        } </span><span style="color: #0000ff;">catch</span><span style="color: #000000;"> (InterruptedException e) {
            e.printStackTrace();
        }
        volatileDemo.running </span>= <span style="color: #0000ff;">false</span><span style="color: #000000;">;
    
    }
    

    }

    复制代码

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

    复制代码
    package com.dingyu;
    

    /**

    • voliatile 不能保证原子性 不能替换synchronized
    • @author dingyu

    */
    public class VolatileDemo02 {
    public volatile int count = 0;

    </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> m1() {
        </span><span style="color: #0000ff;">for</span> (<span style="color: #0000ff;">int</span> i = 0; i &lt;= 10000; i++<span style="color: #000000;">)
            count</span>++<span style="color: #000000;">;
    }
    
    </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> main(String[] args) {
        VolatileDemo02 volatileDemo02 </span>= <span style="color: #0000ff;">new</span><span style="color: #000000;"> VolatileDemo02();
        </span><span style="color: #0000ff;">for</span> (<span style="color: #0000ff;">int</span> i = 0; i &lt; 3; i++<span style="color: #000000;">) {
            </span><span style="color: #0000ff;">new</span> Thread(() -&gt;<span style="color: #000000;"> volatileDemo02.m1()).start();
        }
        </span><span style="color: #0000ff;">try</span><span style="color: #000000;"> {
            Thread.sleep(</span>5000<span style="color: #000000;">);
        } </span><span style="color: #0000ff;">catch</span><span style="color: #000000;"> (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(volatileDemo02.count);
    }
    

    }

    复制代码

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

    复制代码
    package com.dingyu;
    

    import java.util.concurrent.atomic.AtomicInteger;

    /**

    • 原子类 具有原子性,但两个原子类的方法之间不具备原子性
    • @author dingyu

    */
    public class AtomicDemo {
    private AtomicInteger count = new AtomicInteger();

    </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> m1() {
        </span><span style="color: #0000ff;">for</span> (<span style="color: #0000ff;">int</span> i = 0; i &lt; 100; i++<span style="color: #000000;">) {            
            count.incrementAndGet();
            </span><span style="color: #008000;">//</span><span style="color: #008000;">两个原子类的方法之间不具备原子性</span>
    

    count.incrementAndGet();

        }
    }
    

    }

    复制代码

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

    复制代码
    package com.dingyu;
    

    import java.util.concurrent.atomic.AtomicBoolean;

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

    </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> m1() {
        </span><span style="color: #0000ff;">while</span><span style="color: #000000;"> (running.get()) {
    
        }
    }
    
    </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> main(String[] args) {
        AtomicDemo02 demo02 </span>= <span style="color: #0000ff;">new</span><span style="color: #000000;"> AtomicDemo02();
        </span><span style="color: #0000ff;">new</span> Thread(()-&gt;<span style="color: #000000;">demo02.m1()).start();
        demo02.running.set(</span><span style="color: #0000ff;">false</span><span style="color: #000000;">);
    }
    

    }

    复制代码

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

    复制代码
    package com.dingyu;
    

    /**

    • 锁是锁在堆内存的那个对象上,而不是引用
    • @author dingyu

    */
    public class ChangeReference {
    public Object o = new Object();

    </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> m1() {
        </span><span style="color: #008000;">//</span><span style="color: #008000;">锁o</span>
        <span style="color: #0000ff;">synchronized</span><span style="color: #000000;"> (o) {
            </span><span style="color: #0000ff;">while</span> (<span style="color: #0000ff;">true</span><span style="color: #000000;">) {
                </span><span style="color: #0000ff;">try</span><span style="color: #000000;"> {
                    Thread.sleep(</span>1000<span style="color: #000000;">);
                } </span><span style="color: #0000ff;">catch</span><span style="color: #000000;"> (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName());
            }
        }
    }
    
    </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> main(String[] args) {
        ChangeReference changeReference </span>= <span style="color: #0000ff;">new</span><span style="color: #000000;"> ChangeReference();
        </span><span style="color: #0000ff;">new</span> Thread(() -&gt; changeReference.m1(), "t1").start();<span style="color: #008000;">//</span><span style="color: #008000;">启动一个线程 叫t1</span>
        <span style="color: #0000ff;">try</span><span style="color: #000000;"> {
            Thread.sleep(</span>3000<span style="color: #000000;">);
        } </span><span style="color: #0000ff;">catch</span><span style="color: #000000;"> (InterruptedException e) {
            e.printStackTrace();
        }
        changeReference.o </span>= <span style="color: #0000ff;">new</span> Object();<span style="color: #008000;">//</span><span style="color: #008000;">引用变了</span>
        <span style="color: #0000ff;">new</span> Thread(() -&gt; changeReference.m1(),"t2").start();<span style="color: #008000;">//</span><span style="color: #008000;">启动线程 t2</span>
    

    }
    }

    复制代码

     11.不要锁字符串常量

    复制代码
    package com.dingyu;
    /**
     * 不要锁字符串常量
     * @author dingyu
     *
     */
    public class SynchronizedString {
        private String s1 = "hello";
        private String s2 = "hello";
    
    </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> m1() {
        </span><span style="color: #0000ff;">synchronized</span><span style="color: #000000;"> (s1) {
            </span><span style="color: #0000ff;">while</span>(<span style="color: #0000ff;">true</span><span style="color: #000000;">) {}
        }
    }
    
    </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> m2() {
        </span><span style="color: #0000ff;">synchronized</span><span style="color: #000000;"> (s2) {
            System.out.println(</span>"m2 start"<span style="color: #000000;">);
        }
    }
    
    </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> main(String[] args) {
        SynchronizedString synchronizedString </span>= <span style="color: #0000ff;">new</span><span style="color: #000000;"> SynchronizedString();
        </span><span style="color: #0000ff;">new</span> Thread(()-&gt;<span style="color: #000000;">synchronizedString.m1()).start();
        </span><span style="color: #0000ff;">new</span> Thread(()-&gt;<span style="color: #000000;">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();

    </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> m1() {
        </span><span style="color: #0000ff;">synchronized</span><span style="color: #000000;"> (lock) {
            System.out.println(</span>"m1 start"<span style="color: #000000;">);
            </span><span style="color: #0000ff;">for</span> (<span style="color: #0000ff;">int</span> i = 0; i &lt; 10; i++<span style="color: #000000;">) {
                count</span>++<span style="color: #000000;">;
                System.out.println(count);
                </span><span style="color: #0000ff;">if</span> (count == 5<span style="color: #000000;">) {
                    lock.notify();
                    </span><span style="color: #0000ff;">try</span><span style="color: #000000;"> {
                        lock.wait();
                    } </span><span style="color: #0000ff;">catch</span><span style="color: #000000;"> (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
    
        }
    }
    
    </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> m2() {
        </span><span style="color: #0000ff;">synchronized</span><span style="color: #000000;"> (lock) {
            System.out.println(</span>"m2 start"<span style="color: #000000;">);
            </span><span style="color: #0000ff;">if</span> (count != 5<span style="color: #000000;">) {
                </span><span style="color: #0000ff;">try</span><span style="color: #000000;"> {
                    System.out.println(</span>"m2 在等着 但把锁释放了"<span style="color: #000000;">);
                    lock.wait();                    
                } </span><span style="color: #0000ff;">catch</span><span style="color: #000000;"> (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println(</span>"m2 end"<span style="color: #000000;">);
            lock.notify();
        }
    }
    
    </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> main(String[] args) {
        WaitAndNotyifyDemo waitAndNotyifyDemo </span>= <span style="color: #0000ff;">new</span><span style="color: #000000;"> WaitAndNotyifyDemo();
        </span><span style="color: #0000ff;">new</span> Thread(() -&gt;<span style="color: #000000;"> waitAndNotyifyDemo.m2()).start();
        </span><span style="color: #0000ff;">new</span> Thread(() -&gt;<span style="color: #000000;"> waitAndNotyifyDemo.m1()).start();
    }
    

    }

    复制代码
    原文地址:https://www.cnblogs.com/dddyyy/p/9965836.html
  • 相关阅读:
    com.jsj.dao====新闻发布系统(4)
    java类加载器,getClassLoader()
    类名.class的理解
    static{}和{}===静态模块和普通模块的理解
    com.jsj.factory====新闻发布系统(3)
    怎么做(我直接敲代码,有解释)===新闻发布系统(2)
    (8)小项目--界面的代码
    (7) 小项目
    2 Servlet(1)
    RMQ之ST算法模板
  • 原文地址:https://www.cnblogs.com/jpfss/p/10991712.html
Copyright © 2020-2023  润新知