关于java中的synchronized关键字的一些小研究

本文通过对比测试代码的方式,深入浅出地介绍了Java中线程同步的概念。通过具体例子展示了synchronized关键字如何实现线程间的互斥访问,以及不同情况下线程的运行特性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

虽然做java已经两年多了,但说真的对java中所谓的线程同步异步这类的东东还真不是非常的了解,由于最近在研究android上的游戏开发,看到一个游戏demo里到处都充斥着 synchronized这个关键字,而且由于在游戏开发中对线程的使用十分多,所以便写下了这些东东(高手直接忽略就可以了大笑)。

若有幸被高手看到了这篇博文,如果有错误的话请指出,不胜感激。

关于synchronized关键字我自己写了个测试程序运行了一下,具体情况如下:

先把测试代码贴上来看看:

测试代码1:

class TxtThread implements Runnable { int num = 4; String str = new String(); @Override public void run() { // TODO Auto-generated method stub int i = 0; while(i < 5){ synchronized (str) { if(num > 0){ try { System.out.println(Thread.currentThread().getName() + " : " + i); Thread.sleep(500); } catch (InterruptedException e) { // TODO Auto-generated catch block e.getMessage(); } i++; } } } } }


测试代码2:

public class Sync { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub TxtThread tt = new TxtThread(); Thread t1 = new Thread(tt,"A"); Thread t2 = new Thread(tt,"B"); Thread t3 = new Thread(tt,"C"); Thread t4 = new Thread(tt,"D"); t1.start(); t2.start(); t3.start(); t4.start(); } }


运行Sync的结果如下:

运行结果1

第一次运行B : 0 B : 1 B : 2 B : 3 C : 0 C : 1 A : 0 D : 0 A : 1 A : 2 A : 3 C : 2 C : 3 C : 4 B : 4 A : 4 D : 1 D : 2 D : 3 D : 4 ----------- 第二次运行A : 0 A : 1 D : 0 D : 1 D : 2 D : 3 D : 4 B : 0 B : 1 C : 0 C : 1 B : 2 B : 3 B : 4 A : 2 A : 3 A : 4 C : 2 C : 3 C : 4 -----------

从上面的运行结果来看,线程A、B、C、D都是逐个运行的,只不过这四个线程在运行过程中出现了对系统资源的竞争(我是这么理解的),所以导致了上面的情况发生(比如线程A运行了两步然后线程D又运行了三步,我认为这种情况是线程之间对系统资源的竞争引起的),但有一个地方是可以看出来的,线程A、B、C、D并没有同时开始运行,莫非这就是所谓的互斥?


将TxtThread类的run方法中的代码去掉synchronized包裹层去掉,运行结果如下

运行结果2

第一次运行B : 0 D : 0 A : 0 C : 0 B : 1 D : 1 C : 1 A : 1 B : 2 D : 2 C : 2 A : 2 D : 3 B : 3 A : 3 C : 3 D : 4 B : 4 A : 4 C : 4 ----------- 第二次运行A : 0 C : 0 B : 0 D : 0 A : 1 C : 1 B : 1 D : 1 A : 2 B : 2 C : 2 D : 2 A : 3 C : 3 B : 3 D : 3 C : 4 B : 4 A : 4 D : 4

从上面的运行结果来看,线程A、B、C、D是同时开始运行的,莫非这就是所谓的同步访问?

下面的内容引用自http://java.chinaitlab.com/base/818583.html

在java编程思想中对synchronized的一点解释:   1、synchronized关键字的作用域有二种:   1)是某个对象实例内,synchronized aMethod(){}可以防止多个线程同时访问这个对象的synchronized方法(如果一个对象有多个synchronized方法,只要一个线程访问了其中的一个synchronized方法,其它线程不能同时访问这个对象中任何一个synchronized方法)。这时,不同的对象实例的synchronized方法是不相干扰的。也就是说,其它线程照样可以同时访问相同类的另一个对象实例中的synchronized方法;   2)是某个类的范围,synchronized static aStaticMethod{}防止多个线程同时访问这个类中的synchronized static 方法。它可以对类的所有对象实例起作用。   2、除了方法前用synchronized关键字,synchronized关键字还可以用于方法中的某个区块中,表示只对这个区块的资源实行互斥访问。用法是: synchronized(this){/*区块*/},它的作用域是当前对象;   3、synchronized关键字是不能继承的,也就是说,基类的方法synchronized f(){} 在继承类中并不自动是synchronized f(){},而是变成了f(){}。继承类需要你显式的指定它的某个方法为synchronized方法;


从上面引用的内容来看,当测试程序中的TxtThread中的synchronized没有被删除的时候,相当于4个线程(A、B、C、D)同时访问了一个对象的同步方法,那么当线程A、B、C、D全部执行start方法时,它们应该是首先对系统资源进行竞争获得运行时间然后占用TxtThread的run方法中的同步语句块部分,直到某个线程运行完成之后才能允许下一个线程,这样理解的话感觉跟上面的运行结果1不结果不一样,我看了一下资料,我们在TxtThread的run方法中只是对部分关键代码进行了同步,也就是说不同的线程还是可以同时访问TxtThread方法中的run方法的,如果我们将TxtTHread的run方法中的内容写入到另外一个方法runtest()方法中,并将runtest()方法使用synchronized函数进行修饰并将其放到TxtThread的run方法中调用,那么我们就会看到下面的运行效果了,

A : 0 A : 1 A : 2 A : 3 A : 4 D : 0 D : 1 D : 2 D : 3 D : 4 C : 0 C : 1 C : 2 C : 3 C : 4 B : 0 B : 1 B : 2 B : 3 B : 4

这样就符合引用内容中的第一条所说的情况了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值