关于synchronized关键字小谈

这是一个线程,这里注释掉了synchronized同步块,使用Balance类的synchronized static 的同步类方法。



package syncronizedTest;

import java.util.Scanner;

public class Get extends Thread {
	Get() {
		super();
	}

	Get(String name) {
		super(name);
	}

	Balance a = new Balance();

	public void run() {

//		synchronized (Balance.class) {
		try {
			a.say();
			a.speak();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

//		 }

		// int i ;
		// Scanner sc = new Scanner(System.in);
		// i = sc.nextInt();
		// Balance a = new Balance();
		// if (a.dobalance(200)) {
		// System.out.println(getName() + "操作已成功,还剩下 " + a.getbalance());
		// } else {
		// System.out.println(getName() + "余额不足,账户仅剩下 " + " " + a.getbalance());
		// }

	}
}

这是Balance类,say方法是实例方法,speak为同步的类方法。

package syncronizedTest;


public class Balance {
	public static int balance;


	static {
		balance = 800;
	}


	Balance() {


	}


	Balance(int b) {
		balance = b;
	}


	public synchronized void say() {
		for (int i = 0; i < 10; i++)


			System.out.println(Thread.currentThread().getName() + " hihi!");
	}


	public synchronized static void speak() throws InterruptedException {


		for (int i = 0; i < 30; i++) {
			balance++;
			System.out.println(Thread.currentThread().getName() + " " + balance);
			Thread.sleep(10);
		}


	}


	
}



这是测试类


package syncronizedTest;

public class Test {
	public static void main(String[] args) throws InterruptedException {
		for(int i = 0 ; i < 10 ;i++) {
			Get a = new Get(Integer.toString(i++));
			Get b = new Get(Integer.toString(i++));
			Get c = new Get(Integer.toString(i++));
			Get d = new Get(Integer.toString(i));
			a.start();
			b.start();
			c.start();
			d.start();
			a.join();
			b.join();
			c.join();
			d.join();
			//new Balance(800);
		}
		
	}
}


测试一:

先看这种情况下运行的结果。

8 1042
10 hihi!
8 1043
11 hihi!
11 hihi!
11 hihi!
11 hihi!
11 hihi!
11 hihi!
11 hihi!
11 hihi!
11 hihi!
11 hihi!
10 hihi!
10 hihi!
10 hihi!
10 hihi!
10 hihi!
10 hihi!
10 hihi!
10 hihi!
10 hihi!
8 1044
8 1045
8 1046
这里截取了一部分,可以看到不同线程之间speak方法是同步执行的,但是say方法没有(必然,因为不是同步方法)。

测试二:

将Get线程类的synchronized同步块注释解除,现在是synchronized(Balance.class)的样式。去掉speak类的synchronized static 修饰

运行结果如下

9 hihi!
9 hihi!
9 hihi!
9 hihi!
9 hihi!
9 hihi!
9 hihi!
9 hihi!
9 hihi!
9 hihi!
9 1131
9 1132
9 1133
9 1134
9 1135
9 1136
9 1137
可以看到,线程与线程之间完全的同步了。

测试三:

这里测试一下同一个线程的两个同步方法之间是否是同步的。

package t4_threadsafe;

public class NewThread extends Thread {

	public synchronized void speak() {
		for (int i = 0; i < 100; i++) {
			System.out.println(Thread.currentThread().getName() + "speaking... " + i);
		}
	}

	public synchronized void say() throws InterruptedException {
		for (int i = 0; i < 100; i++) {
			System.out.println(Thread.currentThread().getName() + "saying... " + i);
			sleep(10);
		}
	}

	public void run() {
		super.run();
		this.speak();
		try {
			this.say();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public static void main(String[] args) {
		NewThread nt = new NewThread();
//		NewThread nw = new NewThread();
		nt.start();
//		nw.start();
		System.out.println("ending");
	}
}

结果如下:验证猜想,同一个线程的几个同步方法之间是同步的。

Thread-0speaking... 95
Thread-0speaking... 96
Thread-0speaking... 97
Thread-0speaking... 98
Thread-0speaking... 99
Thread-0saying... 0
Thread-0saying... 1
Thread-0saying... 2
Thread-0saying... 3
Thread-0saying... 4
Thread-0saying... 5
但是解开31和33行的注释,两个进程,我们看到结果却是这样。
Thread-1saying... 3
Thread-0saying... 4
Thread-1saying... 4
Thread-0saying... 5
Thread-1saying... 5
Thread-0saying... 6
Thread-1saying... 6
这说明隶属于不同线程的多个个同步方法之间并不是同步执行的(前提都是操作不涉及共用资源,并且也不要是这样的Thread nt = new Thread(t);
Thread nw = new Thread(t); 这样其实算是一个,因为这样构造完了之后run方法其实调用的是t.run(),详细解释见我的另一篇博客点击打开链接http://blog.csdn.net/xuanyuexingxuan/article/details/76575728)。


对于共用资源的直接static synchronized模拟,结果很明显,同步执行。

综上所述:synchronized方法仅仅同步该方法,而synchronized(xxx.class)这种形式则是整个类进行锁定,全部同步(意义不大),威力巨大,就算是没有synchronized修饰的实例方法也会同步。

另注:

1.synchronized()同步块只能监视一个对象 ,必须是对象,因为参数是Object。但是synchronized提供嵌套。

2.对于类变量的同步操作只能依靠synchronized static方法(两个修饰符,缺一不可)或者synchronized(xxx.class)完成,

3.static synchronized 方法与synchronized方法没有尊卑之分,只要隶属于一个线程,同步执行

4.synchronized(xxx.class)威力巨大,对比synchronized static的仅能同步该修饰符所修饰的类方法,synchronized(xxx.class)可以将整个类同步,包括不含synchronized修饰的实例方法!!!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值