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

        虽然做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、付费专栏及课程。

余额充值