如标题所描述,在一个demo里展示了这四种锁的区别。
类锁会造成类中的所有同步方法都被阻塞执行,对象锁能保证一个对象在多线程中的安全性。假设现在有一个order,金额是100元,oder中的方法E和E_1使用了类锁
order如下:
package com.kafkaDemo.sychronized;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Order {
private int amount;
private Object object;
private Lock lock = new ReentrantLock();
public Order(int amount, Object object) {
this.amount = amount;
this.object = object;
}
/**
* 对象锁:普通同步方法,锁为当前实例对象。
*/
public synchronized void doLongTimeTaskA() {
System.out.println("name = " + Thread.currentThread().getName() + " start, amount =" + amount);
try {
amount -= 10;
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("name = " + Thread.currentThread().getName() + " end , amount =" + amount);
}
/**
* 对象锁:同步代码块,锁为代码块里面的实例对象。
*/
public void doLongTimeTaskB() {
synchronized (this) {
System.out.println("name = " + Thread.currentThread().getName() + " start , amount =" + amount);
try {
amount -= 10;
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("name = " + Thread.currentThread().getName() + " end , amount =" + amount);
}
}
/**
* 对象锁:同步代码块,锁为自己的一个私有对象object。
*/
public void doLongTimeTaskC() {
synchronized (object) {
System.out.println("name = " + Thread.currentThread().getName() + " start , amount =" + amount);
try {
amount -= 10;
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("name = " + Thread.currentThread().getName() + " end , amount =" + amount);
}
}
/**
* Lock
*/
public void doLongTimeTaskD() {
lock.lock();
System.out.println("name = " + Thread.currentThread().getName() + " start , amount =" + amount);
try {
amount -= 10;
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("name = " + Thread.currentThread().getName() + " end , amount =" + amount);
lock.unlock();
}
/**
* 类锁
*/
public void doLongTimeTaskE() {
synchronized (Order.class) {
System.out.println("name = " + Thread.currentThread().getName() + " start , amount =" + amount);
try {
amount -= 10;
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("name = " + Thread.currentThread().getName() + " end , amount =" + amount);
}
}
/**
* 类锁
*/
public void doLongTimeTaskE_1() {
synchronized (Order.class) {
System.out.println("name = " + Thread.currentThread().getName() + " start , amount =" + amount);
try {
amount -= 10;
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("name = " + Thread.currentThread().getName() + " end , amount =" + amount);
}
}
/**
* 无锁
*/
public void doLongTimeTask() {
System.out.println("name = " + Thread.currentThread().getName() + " start , amount =" + amount);
try {
amount -= 10;
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("name = " + Thread.currentThread().getName() + " end , amount =" + amount);
}
}
现在新建两个线程类测试,分别执行被类锁控制的方法E和E_1,能够阻塞执行。最终得到90和80两条记录。
public class MyThread_1 extends MyThread {
@Override
public void run() {
// order.doLongTimeTask();
order.doLongTimeTaskE();
}
}
public class MyThread_2 extends MyThread {
@Override
public void run() {
// order.doLongTimeTask();
order.doLongTimeTaskE_1();
}
}
//测试类的main方法:
public static void main(String[] args) {
//测试类锁在多个方法上的影响,可以阻塞执行
Order order1 = new Order(100, new Object());
MyThread thread3 = new MyThread_1();
MyThread thread4 = new MyThread_2();
thread3.setName("thread-3");
thread4.setName("thread-4");
thread3.setOrder(order1);
thread4.setOrder(order1);
thread3.start();
thread4.start();
}
例如,只有一个订单orrder,初始金额100元,线程一减10元保存,线程2再减10元保存,最后会有两条记录,分别是80元和90元,可以借助order中的方法A~方法E实现。
package com.kafkaDemo.sychronized;
public class MyThread extends Thread {
protected Order order;
public Order getOrder() {
return order;
}
public void setOrder(Order order) {
this.order = order;
}
@Override
public void run() {
// 对象锁和retranntLock
// order.doLongTimeTaskA();
// order.doLongTimeTaskB();
// order.doLongTimeTaskC();
// order.doLongTimeTaskD();
//类锁1
order.doLongTimeTaskE();
// 无锁
// order.doLongTimeTask();
}
public static void main(String[] args) {
//测试对象锁、retranntLock和类锁,其中类锁只对方法E起作用,可以执行run中的ABCDE方法
Order order = new Order(100, new Object());
MyThread thread1 = new MyThread();
MyThread thread2 = new MyThread();
thread1.setName("thread-1");
thread2.setName("thread-2");
thread1.setOrder(order);
thread2.setOrder(order);
thread2.start();
thread1.start();
}
}