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));
			}
		}
	}

你可能感兴趣的:(Java,多线程)