Java synchronized关键字总结

        Java的synchronized关键字,主要用来保证线程安全,即每次运行的结果与单个线程运行的结果一的致,避免执行结果出现二义性。当一个线程获得synchronized修饰代码时,其他线程对该代码访问将被阻塞,同一时间只允许一个线程访问该代码。

Java中synchronized关键字用法主要有两种:

  1. synchronized成员方法。
  2. synchronized修饰代码块。
        使用synchronized关键字,最重要的是搞清楚,锁是加在哪个对象身上。

例子1:
package test;

public class SyncDemo1 extends Thread {

 private int threadNo;

 public SyncDemo1(int threadNo) {
  this.threadNo = threadNo;
 }

 public static void main(String[] args) throws InterruptedException {
  for (int i = 0; i < 10; i++) {
   new SyncDemo1(i).start();
   Thread.sleep(1);
  }
 }

 @Override
 public synchronized void run() {
  for (int i = 0; i < 100; i++) {
   System.out.println("No." + (threadNo + 1) + ": " + (i + 1));
  }
 }

}

上面 代码原意是启动10个线程,每个线程打印当前线程号并输出1到100,并且保证 每个线程执行完了,才会去执行其他线程。然而程序执行结果并没有达到预期的效果。synchronized成员方法,控制类成员变量的访问。 上面例子中每个线程持有当前线程对象,显然起不到同步的作用。上面run方法等价于
@Override
 public synchronized void run() {
  synchronized (this) {
   for (int i = 0; i < 100; i++) {
    System.out.println("No." + (threadNo + 1) + ": " + (i + 1));
   }
  }
 }

为了保证10个线程持有相同的锁对象,我们将代码修改如下:
package test;

public class SyncDemo2 extends Thread {

	private int threadNo;
	private static Object lock = new Object();

	public SyncDemo2(int threadNo) {
		this.threadNo = threadNo;
	}

	public static void main(String[] args) throws InterruptedException {
		for (int i = 0; i < 10; i++) {
			new SyncDemo2(i).start();
			Thread.sleep(1);
		}
	}

	@Override
	public void run() {
		synchronized (lock) {
			for (int i = 0; i < 100; i++) {
				System.out.println("No." + (threadNo + 1) + ": " + (i + 1));
			}
		}
	}
}
这样所有的线程持有同一对象lock的锁,达到每个线程内按顺序执行的结果。
我们也可以使用静态的synchronized方法,将锁加在Class上:
package test;

public class SyncDemo3 extends Thread {

	private int threadNo;

	public SyncDemo3(int threadNo) {
		this.threadNo = threadNo;
	}

	public static void main(String[] args) throws Exception {
		for (int i = 1; i < 10; i++) {
			new SyncDemo3(i).start();
			Thread.sleep(1);
		}
	}

	public static synchronized void fun(int threadNo) {
		for (int i = 0; i < 100; i++) {
			System.out.println("No." + (threadNo + 1) + ":" + (i + 1));
		}
	}

	@Override
	public void run() {
		fun(threadNo);
	}
}
等价于:
@Override
	public void run() {
		synchronized (LockDemo1.class) {
			for (int i = 0; i < 100; i++) {
				System.out.println("No." + (threadNo + 1) + ": " + (i + 1));
			}
		}
	}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值