线程基础(二)

一、多个线程多个锁

多个线程多个锁:多个线程,每个线程都可以拿到自己指定的锁,分别获得锁之后,执行synchronized方法体的内容。

代码如下:

public class MultiThread {
private static int num = 0;
private synchronized void printNum(String tag) {
try {
if (tag.equals("a")) {
num = 100;
System.out.println("tag a , set nunm over");
Thread.sleep(1000);
} else {
num = 200;
System.out.println("tag b , set nunm 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();
}
}

假设线程是被t1锁住的,运行后的结果应该是:

tag a , set nunm over
tag a,num = 100
tag b , set nunm over
tag b,num = 200

实际的运行结果不是这样的,实际的结果是

tag a , set nunm over
tag b , set nunm over
tag b,num = 200
tag a,num = 200

是因为,一个对象有一把锁,这个案例里面有两个对象,所以说t1的线程调用printNum(),肯定看到方式被synchronized修饰了,但是t1线程看到的锁是m1对象的锁;第二个线程在里面看到的是m2对像的锁,他们之间没有任何的冲突,自己执行自己的,所以对应的运行结果才会是上面的结果,不会用任何同步的效果;

如果说有一天想要说当前只要有一个线程执行printNum()方法,我就不希望有其他线程再来执行这个方法,有一种凡事可以来解决这个问题,用static来修饰printNum()方法,表示在静态的方法上,用synchronized关键字来修饰,那线程获得的锁,就是class类级别的锁,无论实例化多少个对象,都是没有关系的。就是t1和t2的执行顺序是有限制的,运行后,就是第一种结果。





原文地址:https://www.cnblogs.com/shmilyToHu/p/6381384.html