Java多线程编程概述
Java多线程的安全问题
Java多线程同步
Java多线程间的通信
Java线程Lock
Java多线程管理
保障线程安全的设计技术
Java锁的优化及注意事项
Java多线程集合
【Java多线程】单例模式与多线程

Java多线程同步代码块Synchronized

Java中的每个对象都有一个与之关联的内部锁(Intrinsic lock). 这种锁也称为监视器(Monitor), 这种内部锁是一种排他锁,可以保障原子性,可见性与有序性。

内部锁是通过synchronized关键字实现的.synchronized关键字修饰代码块,修饰该方法。

修饰代码块的语法:

synchronized( 对象锁 ) {
   同步代码块,可以在同步代码块中访问共享数据
}

修饰实例方法就称为同步实例方法

修饰静态方法称称为同步静态方法

synchronized同步代码块

package com.wkcto.intrinsiclock;

/**
 * synchronized同步代码块
 *  this锁对象
 * Author: 老崔
 */
public class Test01 {
    public static void main(String[] args) {
        //创建两个线程,分别调用mm()方法
        //先创建Test01对象,通过对象名调用mm()方法
        Test01 obj = new Test01();

        new Thread(new Runnable() {
            @Override
            public void run() {
                obj.mm();       //使用的锁对象this就是obj对象
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                obj.mm();       //使用的锁对象this也是obj对象
            }
        }).start();

    }

    //定义方法,打印100行字符串
    public void mm(){
        synchronized ( this ) {     //经常使用this当前对象作为锁对象
            for (int i = 1; i <= 100; i++) {
                System.out.println(Thread.currentThread().getName() + " --> " + i);
            }
        }
    }
}
package com.wkcto.intrinsiclock;

/**
 * synchronized同步代码块
 *  如果线程的锁不同, 不能实现同步
 *  想要同步必须使用同一个锁对象
 * Author: 老崔
 */
public class Test02 {
    public static void main(String[] args) {
        //创建两个线程,分别调用mm()方法
        //先创建Test01对象,通过对象名调用mm()方法
        Test02 obj = new Test02();
        Test02 obj2 = new Test02();

        new Thread(new Runnable() {
            @Override
            public void run() {
                obj.mm();       //使用的锁对象this就是obj对象
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                obj2.mm();       //使用的锁对象this也是obj2对象
            }
        }).start();

    }

    //定义方法,打印100行字符串
    public void mm(){
        synchronized ( this ) {     //经常使用this当前对象作为锁对象
            for (int i = 1; i <= 100; i++) {
                System.out.println(Thread.currentThread().getName() + " --> " + i);
            }
        }
    }
}
package com.wkcto.intrinsiclock;

/**
 * synchronized同步代码块
 * 使用一个常量对象作为锁对象
 * Author: 老崔
 */
public class Test03 {
    public static void main(String[] args) {
        //创建两个线程,分别调用mm()方法
        //先创建Test01对象,通过对象名调用mm()方法
        Test03 obj = new Test03();
        Test03 obj2 = new Test03();

        new Thread(new Runnable() {
            @Override
            public void run() {
                obj.mm();       //使用的锁对象OBJ常量
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                obj2.mm();       //使用的锁对象OBJ常量
            }
        }).start();

    }

    public static final  Object OBJ = new Object();     //定义一个常量,
    //定义方法,打印100行字符串
    public void mm(){
        synchronized ( OBJ ) {     //使用一个常量对象作为锁对象
            for (int i = 1; i <= 100; i++) {
                System.out.println(Thread.currentThread().getName() + " --> " + i);
            }
        }
    }
}
package com.wkcto.intrinsiclock;

/**
 * synchronized同步代码块
 * 使用一个常量对象作为锁对象,不同方法中 的同步代码块也可以同步
 * Author: 老崔
 */
public class Test04 {
    public static void main(String[] args) {
        //创建两个线程,分别调用mm()方法
        //先创建Test01对象,通过对象名调用mm()方法
        Test04 obj = new Test04();
        Test04 obj2 = new Test04();

        new Thread(new Runnable() {
            @Override
            public void run() {
                obj.mm();       //使用的锁对象OBJ常量
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                obj2.mm();       //使用的锁对象OBJ常量
            }
        }).start();

        //第三个线程调用静态方法
        new Thread(new Runnable() {
            @Override
            public void run() {
                sm();       //使用的锁对象OBJ常量
            }
        }).start();

    }

    public static final  Object OBJ = new Object();     //定义一个常量,
    //定义方法,打印100行字符串
    public void mm(){
        synchronized ( OBJ ) {     //使用一个常量对象作为锁对象
            for (int i = 1; i <= 100; i++) {
                System.out.println(Thread.currentThread().getName() + " --> " + i);
            }
        }
    }

    //定义方法,打印100行字符串
    public static void sm(){
        synchronized ( OBJ ) {     //使用一个常量对象作为锁对象
            for (int i = 1; i <= 100; i++) {
                System.out.println(Thread.currentThread().getName() + " --> " + i);
            }
        }
    }
}