多线程--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、多个线程访问对象变量,出现非线程安全问题
3、创建多个对象会产生多个锁
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关键字,才可以实现同步运行
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 |
改动 | 在run类中创建多个HasSelfPrivateNum实例对象即可 |
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应用——synchronized方法
- Java:多线程,线程同步,synchronized关键字的用法(同步代码块、非静态同步方法、静态同步方法)
- 多线程编程-Synchronized同步方法(二)
- (转)初学Java多线程:使用Synchronized关键字同步类方法
- JavaSE8基础 多线程synchronized 同步的成员方法用的锁对象是this
- java多线程编程之使用Synchronized关键字同步类方法
- 初学Java多线程:使用Synchronized关键字同步类方法
- 从头认识多线程-2.25 synchronized同步方法在jvm是怎样执行的?
- JavaSE8基础 多线程synchronized 同步静态方法的锁
- 四、java多线程核心技术——synchronized同步方法与synchronized同步快
- 【Java面试题】26 多线程有几种实现方法?同步有几种实现方法? 当一个线程进入一个对象的一个synchronized方法后,其它线程是否可进入此对象的其它方法?
- java多线程之-----对象及变量的并发访问1(synchronized同步方法)
- java 多线程 方法1 继承Thread 加入同步synchronized代码块
- 初学Java多线程:使用Synchronized关键字同步类方法
- 从头认识多线程-2.14 解决由同步的synchronized (newobject()) 引起的脏读的方法
- 从头认识多线程-2.19 synchronized同步方法的无限等待与解决方法
- Java多线程3.1:synchronized同步方法
- 九、初学Java多线程:使用Synchronized关键字同步类方法
- 【JAVA】多线程之synchronized 同步数据 方法
- java多线程之-----静态同步synchronized方法与synchronized(class) 代码块