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
原文地址:https://www.cnblogs.com/jpfss/p/10991712.html