package 对象及变量的并发访问2;
/**
* 多个对象多个锁
*
* 如果先输出 a set over! a=100 然后输出 b set over b=1200 就是同步,而如果输出 a set over 后 输出 b set over 就是异步
*
* 本示例中,创建了两个业务(A+B),在系统中产生两个锁,线程和业务对象属于一对一的关系,每个线程执行自己所属的业务对象中的同步方法,
*不存在争抢关系,所以运行结果是异步的,另外,在这种情况下,synchronized可以不需要,线程和业务对象属于多对一的关系,为了避免出现
* 非线程安全问题,所以使用synchronized。
* 从程序结果看,虽然HasSelfPrivateNumT214使用了synchronized关键字,但输出顺序不是同步的,而是交叉的,关键字synchronized取得
*的锁都是对象锁,而不是把一段代码或方法当作锁,所以在代码中,那个线程先执行synchronized关键字的方法,那个线程就持有该方法所属对象的
* 锁Lock,那么其他线程只能处于等待状态,前提是多个线程访问的是同一个对象。但如果多个线程访问多个对象,也就是每个线程访问自己所属的业务
* 对象(如代码),则JVM会创建多个锁,不存在锁争抢的情况,代码中创建了两个实例变量,每个线程访问自己的实例变量,所以不加synchronized
* 关键字都是线程安全的。
*
*
*/
class HasSeifPrivateNumT214{
private int num=0;
public void addI(String usrname){
try {
if(usrname.equals("a")){
num=100;
System.out.println("a set over!");
Thread.sleep(2000);
}else {
num=200;
System.out.println("b set over!");
}
System.out.println(usrname+"name="+num);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
class MyThreadAT214 extends Thread{
private HasSeifPrivateNumT214 numRef;
public MyThreadAT214(HasSeifPrivateNumT214 numRef){
super();
this.numRef=numRef;
}
@Override
public void run() {
super.run();
numRef.addI("a");
}
}
class MyThreadBT214 extends Thread{
private HasSeifPrivateNumT214 numT214;
public MyThreadBT214(HasSeifPrivateNumT214 numT214){
super();
this.numT214=numT214;
}
@Override
public void run() {
super.run();
numT214.addI("b");
}
}
/**
* 运行
*/
class RunT214 {
public RunT214(){
HasSeifPrivateNumT214 numT214=new HasSeifPrivateNumT214();
HasSeifPrivateNumT214 numT2141=new HasSeifPrivateNumT214();
MyThreadAT214 at214=new MyThreadAT214(numT214);
at214.start();
MyThreadBT214 bt214=new MyThreadBT214(numT2141);
bt214.start();
}
}
public class T2104 {
public static void main(String[] args) {
RunT214 runT214=new RunT214();
}
}
多个对象多个锁——T2104
最新推荐文章于 2022-08-01 10:40:04 发布