您的位置:首页 > 其它

多线程--synchronized同步方法

2018-03-04 14:33 239 查看
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关键字,才可以实现同步运行
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐