多线程--synchronized同步方法
Posted z-xiaoyao
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了多线程--synchronized同步方法相关的知识,希望对你有一定的参考价值。
1、方法中的变量不存在非线程安全问题
HasSelfPrivateNum publicclassHasSelfPrivateNum
publicvoidaddI(Stringusername)
try
intnum=0;
if(username.equals("a"))
num=100;
System.out.println("asetover");
Thread.sleep(2000);
else
num=200;
System.out.println("bsetover");
System.out.println(username+"num="+num);
catch(InterruptedExceptione)
e.printStackTrace();
ThreadA publicclassThreadAextendsThread
privateHasSelfPrivateNumnumRef;
publicThreadA(HasSelfPrivateNumnumRef)
super();
this.numRef=numRef;
@Override
publicvoidrun()
super.run();
numRef.addI("a");
ThreadB publicclassThreadBextendsThread
privateHasSelfPrivateNumnumRef;
publicThreadB(HasSelfPrivateNumnumRef)
super();
this.numRef=numRef;
@Override
publicvoidrun()
super.run();
numRef.addI("b");
Run publicclassRun
publicstaticvoidmain(String[]args)
HasSelfPrivateNumnumRef=newHasSelfPrivateNum();
ThreadAathread=newThreadA(numRef);
athread.start();
ThreadBbthread=newThreadB(numRef);
bthread.start();
2、多个线程访问对象变量,出现非线程安全问题
改动 | private intnum=0放在类中,而不是方法中 |
结果 | 值被覆盖(出现线程安全问题) |
解决 | addI方法上加synchronized |
3、创建多个对象会产生多个锁
改动 | 在run类中创建多个HasSelfPrivateNum实例对象即可 |
4、A线程先持有object对象的Lock锁,B线程可以以异步的方式调用object对象中的非synchronized类型的方法
A线程先持有object对象的Lock锁,B线程如果在这时调用object对象中的synchronized类型的方法则需要等待,也就是同步
MyObject publicclassMyObject
synchronizedpublicvoidmethodA()
try
System.out.println("beginmethodAthreadName="+Thread.currentThread().getName());
Thread.sleep(5000);
System.out.println("endendTime="+System.currentTimeMillis());
catch(InterruptedExceptione)
e.printStackTrace();
synchronizedpublicvoidmethodB()
try
System.out.println("beginmethodBthreadName="+Thread.currentThread().getName()+"begintime="+System.currentTimeMillis());
Thread.sleep(5000);
System.out.println("end");
catch(InterruptedExceptione)
e.printStackTrace();
ThreadA publicclassThreadAextendsThread
privateMyObjectobject;
publicThreadA(MyObjectobject)
super();
this.object=object;
@Override
publicvoidrun()
super.run();
object.methodA();
ThreadB publicclassThreadBextendsThread
privateMyObjectobject;
publicThreadB(MyObjectobject)
super();
this.object=object;
@Override
publicvoidrun()
super.run();
object.methodB();
Run publicclassRun
publicstaticvoidmain(String[]args)
MyObjectobject=newMyObject();
ThreadAa=newThreadA(object);
a.setName("A");
ThreadBb=newThreadB(object);
b.setName("B");
a.start();
b.start();
5、脏读
A线程调用anyObject对象加入synchronized关键字的X方法时,其他线程必须等A线程执行完毕才可以调用X方法,但B线程可以随意调用其他非synchronized同步方法
A线程调用anyObject对象加入synchronized关键字的X方法时,B线程如果调用synchronized关键字的非X方法时,必须等A线程将X方法执行完才可以调用
6、synchronized锁重入
一个synchronized方法的内部调用本类的其他synchronized方法时,是可以得到锁的
当存在父子类继承关系时,子类完全可以通过“可重入锁”调用父类的同步方法
7、 a线程出现异常并释放锁,b线程进入方法正常打印,也就是说出现异常的锁被自动释放了
Service publicclassService
synchronizedpublicvoidtestMethod()
if(Thread.currentThread().getName().equals("a"))
System.out.println("ThreadName="+Thread.currentThread().getName()+"runbeginTime="+System.currentTimeMillis());
inti=1;
while(i==1)
if((""+Math.random()).substring(0,8).equals("0.123456"))
System.out.println("ThreadName="+Thread.currentThread().getName()+"runexceptionTime="+System.currentTimeMillis());
Integer.parseInt("a");
else
System.out.println("ThreadBrunTime="+System.currentTimeMillis());
ThreadA publicclassThreadAextendsThread
privateServiceservice;
publicThreadA(Serviceservice)
super();
this.service=service;
@Override
publicvoidrun()
service.testMethod();
ThreadB publicclassThreadBextendsThread
privateServiceservice;
publicThreadB(Serviceservice)
super();
this.service=service;
@Override
publicvoidrun()
service.testMethod();
Run publicclassRun
publicstaticvoidmain(String[]args)
try
Serviceservice=newService();
ThreadAa=newThreadA(service);
a.setName("a");
a.start();
Thread.sleep(500);
ThreadBb=newThreadB(service);
b.setName("b");
b.start();
catch(InterruptedExceptione)
e.printStackTrace();
8、同步不能继承,父类的方法中有synchronized关键字,运行子类的方法时,必须在子类的方法中添加synchronized关键字,才可以实现同步运行
以上是关于多线程--synchronized同步方法的主要内容,如果未能解决你的问题,请参考以下文章
java 多线程系列基础篇之 synchronized关键字