synchronized

2019-12-08  本文已影响0人  花_清

demo1
package syndemo1;

/**

demo2
package syndemo2;

public class T2 {
private int count = 2;

public static void main(String[] args) {
    T2 t = new T2();
    t.m();
}

/**
 * 任何线程要执行下面的代码,先要给this加锁,这里是给自身加锁。或者说要用这个方法,要先new一个T的对象指向自身。
 * 也就是说this就是T2的对象。
 *
 * m()方法里面“一开始就对this加锁了”,对这种有个简单的写法,见T3。
 */
public void m(){
    synchronized (this){
        count--;
        System.out.println("线程名:"+Thread.currentThread().getName()+"    count:"+count);
    }
}

}

demo3
package syndemo3;

public class T3 {
private int count = 3;

public static void main(String[] args) {
    T3 t = new T3();
    t.m();
}

/**
 * 对T2里面的简单写法如下。这个例子里面锁定的是当前对象this。
 */
public synchronized void m(){
    count--;
    System.out.println("线程名:"+Thread.currentThread().getName()+"    count:"+count);
}

}

demo4
package syndemo4;
public class T4 {
private static int count = 4;

public static void main(String[] args) {
   m();//这里也可以写为T4.m()
   mm();//这里也可以写为T4.mm()
}

/**
 *这里m()方法和mm()方法中的两个加锁的效果是一样的。
 * 我们知道万物皆对象,T4.class是将类抽象成了一个对象。
 * 静态方法里面synchronized加锁的对象是当前类的class对象。
 */
public synchronized static void m(){
    count--;
    System.out.println("线程名:"+Thread.currentThread().getName()+"    count:"+count);
}

public static void mm(){
    /**
     * 静态属性和静态方法的调用是类名.类方法或类名.类属性,这个时候调用方法的时候是没有new一个对象的,所以下面这行代码里
     * 就不能写synchronized(this)。即这里不能给this加锁!这个时候锁定的是当前类的class对象。
     */
    synchronized (T4.class){
        count--;
        System.out.println("线程名:"+Thread.currentThread().getName()+"    count:"+count);
    }
}

}

demo5
package syndemo5;

public class T5 implements Runnable{
private int count = 10;
public /synchronized/ void run() {
count--;
System.out.println("线程名:"+Thread.currentThread().getName()+" count:"+count);
}

public static void main(String[] args) {
    T5 t = new T5();
    for(int i = 0; i < 5; i++){
        new Thread(t, "THREAD" + i).start();
    }
}
/**
 * 多次运行之后,可能会拿到如下结果:
 * 线程名:THREAD1    count:8
 * 线程名:THREAD0    count:8
 * 线程名:THREAD2    count:7
 * 线程名:THREAD3    count:6
 * 线程名:THREAD4    count:5
 * 分析:1、上面的代码中只new了一个T5的对象t,而不是在每个线程中都new了对象。所以这些线程是共同访问这个对象的。
 * 2、这5个线程访问的是同一个count,count在堆里面,t在栈里面。
 * 3、这里对运行结果做个分析。第一个线程count--之后还没有打印之前,第二个线程进来了,做了个count--操作,这时候
 *第一个线程才开始打印结果,第二个线程也随之打印,所以前两个线程打印的结果都是count--再count--的结果,即8,后边的三个
 * 线程都是count--立马打印,即结果正确。
 * 解决办法。只要将上面的synchronized打开给加上锁,重复多次执行拿到的结果都是正确的。这里不展示测试结果了。
 */

}

demo6
package syndemo6;
/**

demo7
package syndemo7;
import java.util.concurrent.TimeUnit;
/**

// new Thread(new Runnable() {//开启一个线程,调用setMoney()方法
// @Override
// public void run() {
// account.setMoney("张三",101.0);
// }
// }).start();

    //开启一个线程,调用setMoney()方法。下面这行代码等同于上面注释的六行代码
    new Thread(()->account.setMoney("张三",100.0)).start();

    try {
        TimeUnit.SECONDS.sleep(1);//线程休息1秒
    } catch (InterruptedException e) {
        e.printStackTrace();
    }

    System.out.println(account.getMoney("张三"));//查询张三的钱

    try {
        TimeUnit.SECONDS.sleep(2);//线程休息2秒
    } catch (InterruptedException e) {
        e.printStackTrace();
    }

    System.out.println(account.getMoney("张三"));//查询张三的钱
}

}

demo8
package syndemo8;
import java.util.concurrent.TimeUnit;
/**

demo9
package syndemo9;
/**

demo10
package syndemo1011;
import java.util.concurrent.TimeUnit;
/**

demo11
package syndemo12;
import java.util.concurrent.TimeUnit;
/**

}

上一篇下一篇

猜你喜欢

热点阅读