线程安全-002-多个线程多把锁&类锁

时间:2024-01-12 16:38:14

一、多个对象多把锁

线程安全-002-多个线程多把锁&类锁

例子代码:

package com.lhy.thread01;

public class MultiThread {

    //static
private int num = 0; //加上static后就是类级别的锁。不加,是对象级别的锁,此时多个线程之间是互不干扰
public synchronized void printNum(String tag){
try{
if("a".equals(tag)){
num = 100;
System.out.println("tag a ,set num over!");
Thread.sleep(1000);//a会睡1秒,b不会
}else{
num = 200;
System.out.println("tag b ,set num over!");
}
System.out.println("tag "+ tag +" , num = "+ num);
}catch(Exception e){
e.printStackTrace();
}
} public static void main(String[] args) {
//两个不同的对象
final MultiThread m1 = new MultiThread();
final MultiThread m2 = new MultiThread(); Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
m1.printNum("a");
}
}); Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
m2.printNum("b");
}
}); t1.start();
t2.start();
} }

执行结果:

线程安全-002-多个线程多把锁&类锁

关键字synchornized获得的锁是对象锁,哪个线程先执行synchornized关键字的方法,哪个线程就持有该方法所属对象的锁,例子程序中,由于m1和m2是两个不同的对象,t1 线程获得 m1对象的锁,t2线程获得m2对象的锁,所以互不影响。

线程安全-002-多个线程多把锁&类锁

验证, 如果将main方法改为如下所示,t1 和 t2 线程都执行m1对象的printNum方法,此时两个线程在抢一把锁,所以执行会按顺序来:

public static void main(String[] args) {
//两个不同的对象
final MultiThread m1 = new MultiThread();
//final MultiThread m2 = new MultiThread(); Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
m1.printNum("a");
}
}); Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
m1.printNum("b");
}
}); t1.start();
t2.start();
}

线程安全-002-多个线程多把锁&类锁

二、多个对象一把锁(类锁)

在静态方法上加上synchornized关键字,表示锁定.class类,类一级别的锁(独占.class 类)

例子程序:

public class MultiThread {

    //static
private static int num = 0; //加上static后就是类级别的锁。不加,是对象级别的锁,此时多个线程之间是互不干扰
public static synchronized void printNum(String tag){
try{
if("a".equals(tag)){
num = 100;
System.err.println("tag a ,set num over!");
Thread.sleep(1000);//a会睡1秒,b不会
}else{
num = 200;
System.err.println("tag b ,set num over!");
}
System.err.println("tag "+ tag +" , num = "+ num);
}catch(Exception e){
e.printStackTrace();
}
} public static void main(String[] args) {
//两个不同的对象
final MultiThread m1 = new MultiThread();
final MultiThread m2 = new MultiThread(); Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
m1.printNum("a");
}
}); Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
m2.printNum("b");
}
}); t1.start();
t2.start();
} }

执行结果:

线程安全-002-多个线程多把锁&类锁

是按照t1、t2 顺序执行的。

线程安全-002-多个线程多把锁&类锁