Java中的每个对象都有一个与之关联的内部锁(Intrinsic lock). 这种锁也称为监视器(Monitor), 这种内部锁是一种排他锁,可以保障原子性,可见性与有序性。
内部锁是通过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);
}
}
}
}