java进程同步时使用关键字synchronized修饰的方法为什么仍然可以同时被多个对象调用?

代码功能:实现依次输出英文字母表和希腊字母表
问题:未实现线程同步

public class 线程同步 {
	public static void main(String[] args){
		Thread e=new Thread(new Letter());
		e.setName("英文字母");
		Thread g=new Thread(new Letter());
		g.setName("希腊字母");
		e.start();
		g.start();
	}
}
 class Letter implements Runnable{

	public void run(){
		Print();
	}
	public synchronized  void Print(){
		if(Thread.currentThread().getName().equals("英文字母")){
			System.out.println("输出英文字母");
			  for(int i=0;i<26;i++){
		            System.out.println("英文字母"+(char)(i+65));
		        }
		        //小写字母a 97
		        for(int i=0;i<26;i++){
		            System.out.println("英文字母"+(char)(i+97));
		        }
		}
		else if(Thread.currentThread().getName().equals("希腊字母")){
			System.out.println("输出希腊字母");
			/*try{wait();}
			catch (InterruptedException e){}*/
			for(int i=945;i<970;i++){
		           //希腊字母 945-969,除去962
		           if(i==962)continue;
		            System.out.println("希腊字母"+(char)(i));
		        }
		}
	}
}

结果

输出希腊字母
输出英文字母
希腊字母α
希腊字母β
希腊字母γ
希腊字母δ
希腊字母ε
希腊字母ζ
希腊字母η
希腊字母θ
希腊字母ι
希腊字母κ
希腊字母λ
希腊字母μ
希腊字母ν
希腊字母ξ
希腊字母ο
希腊字母π
希腊字母ρ
希腊字母σ
希腊字母τ
英文字母A
英文字母B
英文字母C
英文字母D
英文字母E
英文字母F
英文字母G
希腊字母υ
希腊字母φ
希腊字母χ
希腊字母ψ
希腊字母ω
英文字母H
英文字母I
英文字母J
英文字母K
英文字母L
英文字母M
英文字母N
英文字母O
英文字母P
英文字母Q
英文字母R
英文字母S
英文字母T
英文字母U
英文字母V
英文字母W
英文字母X
英文字母Y
英文字母Z
英文字母a
英文字母b
英文字母c
英文字母d
英文字母e
英文字母f
英文字母g
英文字母h
英文字母i
英文字母j
英文字母k
英文字母l
英文字母m
英文字母n
英文字母o
英文字母p
英文字母q
英文字母r
英文字母s
英文字母t
英文字母u
英文字母v
英文字母w
英文字母x
英文字母y
英文字母z

修改:只有主函数进行了改动,即将创建线程使用的对象改为同一个对象

public static void main(String[] args){
		Thread e=new Thread(new Letter());
		e.setName("英文字母");
		Thread g=new Thread(new Letter());
		g.setName("希腊字母");
		e.start();
		g.start();
	}

	public static void main(String[] args){
		Letter L=new Letter();
		Thread e=new Thread(L);
		e.setName("英文字母");
		Thread g=new Thread(L);
		g.setName("希腊字母");
		e.start();
		g.start();
	}

原因:

  1. 修饰一个代码块,被修饰的代码块称为同步语句块,其作用的范围是大括号{}括起来的代码,作用的对象是调用这个代码块的对象;
  2. 修饰一个方法,被修饰的方法称为同步方法,其作用的范围是整个方法,作用的对象是调用这个方法的对象;
  3. 修改一个静态的方法,其作用的范围是整个静态方法,作用的对象是这个类的所有对象;
  4. 修改一个类,其作用的范围是synchronized后面括号括起来的部分,作用主的对象是这个类的所有对象。

原因参考:
原文链接:https://blog.csdn.net/luoweifu/article/details/46613015

发现自己语文学的不怎么样啊,此刻才理解了什么叫这个类和所有类。尽管是用synchronized修饰的方法,但我最开始的代码使用了同一个类的两个对象去调用这个方法,进程锁失效,哎,真实一手懒造成千古恨!

回看了java课表,发现课本上有一段话说的直接易懂:当两个或者多个线程同时访问同一个变量,并且一些线程需要修改这个变量,程序应该对这个问题做出处理,否则可能发生混乱。这就是线程同步/线程锁的本质,因此,当synchronized修饰一个普通方法的时候,只对同一个对象的线程有线程锁的限制。至于两个对象之间,虽然调用同一个方法,但是是对各种的变量进行操作,互不干扰,因此不存在线程锁的问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值