Java 中synchronize函数的实例详解
Java中synchronize函数的实例详解
java中的一个类的成员函数若用synchronized来修饰,则对应同一个对象,多个线程像调用这个对象的这个同步函数时必须等到上一个线程调用完才能由下一个线程调用。
那么如果一个类同时有两个成员函数是由synchronized修饰如代码所示,对与同一个对象,是否可以在两个线程运行时,一个调用funcA,同时另一个调用funcB?
Mysyn是这样一个类,如果我有两个线程,一个在run方法中先运行funcA再运行funcB,另一个线程在run方法中先运行funcB再运行funcA。那有没有可能出现这样的情况:在输出时startA...后面直接输出startB...?
publicclassMySyn{ publicsynchronizedvoidfuncA(Stringstr){ System.out.println(str+":"); System.out.println("startA..."); try{ Thread.sleep(5000); }catch(InterruptedExceptione){ //TODOAuto-generatedcatchblock e.printStackTrace(); } System.out.println("...Aend"); } publicsynchronizedvoidfuncB(Stringstr){ System.out.println(str+":"); System.out.println("startB..."); try{ Thread.sleep(5000); }catch(InterruptedExceptione){ //TODOAuto-generatedcatchblock e.printStackTrace(); } System.out.println("...Bend"); } }
测试代码如下:
这个线程是先运行funcA的
publicclassMythreadimplementsRunnable{ privateMySynmysyn; privateStringid; publicMythread(MySynsyn,Stringid){ this.mysyn=syn; this.id=id; } @Override publicvoidrun(){ this.mysyn.funcA(id); try{ Thread.sleep(1000); }catch(InterruptedExceptione){ //TODOAuto-generatedcatchblock e.printStackTrace(); } this.mysyn.funcB(id); } publicstaticvoidmain(Stringarg[]){ MySynsyn=newMySyn(); Threadt1=newThread(newMythread(syn,"t1")); Threadt2=newThread(newYourThread(syn,"t2")); t1.start(); t2.start(); } }
这个线程是先运行funcB的
publicclassYourThreadimplementsRunnable{ privateMySynmysyn; privateStringid; publicYourThread(MySynsyn,Stringid){ this.mysyn=syn; this.id=id; } @Override publicvoidrun(){ this.mysyn.funcB(id); this.mysyn.funcA(id); } }
输出结果多是:
t1: startA... ...Aend t2: startB... ...Bend t2: startA... ...Aend t1: startB... ...Bend
如果取消Mythread的run方法中两个函数调用间的sleep,那结果多是:
t1: startA... ...Aend t1: startB... ...Bend t2: startB... ...Bend t2: startA... ...Aend
个人结果可能因线程调度不同,但是永远不会有:startA...后面直接输出startB...
那如果funcB不是一个同步函数,那上述代码运行结果会是怎么样呢?
代码稍加改动,把funcB的synchronized关键字去掉。运行结果为:
t2: t1: startA... startB... ...Aend t1: startB... ...Bend t2: startA... ...Bend ...Aend
显然出现了startA...后面直接输出startB...的结果。
同样如果Mysyn类如果有一个public的成员变量,多线程也可以再同步函数被调用的同时,由另一个线程修改这个成员变量。
上述实验说明了:同步的成员函数只能在同一个对象的同步函数调用中对其他同步函数(包括本身)有排它的效果,即多线程运行中,同一个对象当前只能有一个同步函数在运行,但不排除其他非同步函数的运行或对成员进行访问。
那现在假设某个类有两个静态同步方法,那情况怎么样呢?
具体实现,我就不重复了,因为结果类似:
在多线程中,同一个类,当前只能有一个类同步函数(静态同步函数)在运行,但不排除其他非同步静态函数的运行或对静态成员的访问
如有疑问请留言或者到本站社区交流讨论,感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!