程序1:

package testsynchronized;

public class Thread1 implements Runnable {

	@Override
	public void run() {
		synchronized (this) {
			for (int i = 0; i < 10; i++) {
				System.out.println(Thread.currentThread().getName()
						+ " synchronized loop " + i);
			}
		}
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		Thread1 t1 = new Thread1();
		Thread ta = new Thread(t1, "A");
		Thread tb = new Thread(t1, "B");
		ta.start();
		tb.start();
	}

}



输出:

A synchronized loop 0
A synchronized loop 1
A synchronized loop 2
A synchronized loop 3
A synchronized loop 4
A synchronized loop 5
A synchronized loop 6
A synchronized loop 7
A synchronized loop 8
A synchronized loop 9
B synchronized loop 0
B synchronized loop 1
B synchronized loop 2
B synchronized loop 3
B synchronized loop 4
B synchronized loop 5
B synchronized loop 6
B synchronized loop 7
B synchronized loop 8
B synchronized loop 9



因为a先运行,b后运行,所以a先输出,b后输出,而且不会出现a和b并发输出,因为a已经获得了Thread1的对象锁。


程序2:

package testsynchronized;

public class Thread2 {
	public void m1() {
		synchronized (this) {
			int i = 10;
			while (i-- > 0) {
				System.out.println(Thread.currentThread().getName() + " : " + i);
				try {
					Thread.sleep(3000);
				} catch (InterruptedException ie) {
				}
			}
		}
	}

	public void m2() {
		int i = 10;
		while (i-- > 0) {
			System.out.println(Thread.currentThread().getName() + " : " + i);
			try {
				Thread.sleep(1000);
			} catch (InterruptedException ie) {
			}
		}
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		final Thread2 myt2 = new Thread2();
		Thread t1 = new Thread(new Runnable() {
			public void run() {
				myt2.m1();
			}
		}, "t1");
		Thread t2 = new Thread(new Runnable() {
			public void run() {
				myt2.m2();
			}
		}, "t2");
		t1.start();
		t2.start();
	}

}



输出:

t2 : 9
t1 : 9
t2 : 8
t2 : 7
t2 : 6
t1 : 8
t2 : 5
t2 : 4
t1 : 7
t2 : 3
t2 : 2
t2 : 1
t2 : 0
t1 : 6
t1 : 5
t1 : 4
t1 : 3
t1 : 2
t1 : 1
t1 : 0



这个输出不唯一。

可以看出,当一个线程运行同步代码块时,另一个线程可以同时运行非同步代码块。


程序3:

package testsynchronized;

public class Thread3 {
	public void m1() {
		synchronized (this) {
			int i = 10;
			while (i-- > 0) {
				System.out
						.println(Thread.currentThread().getName() + " : " + i);
				try {
					Thread.sleep(500);
				} catch (InterruptedException ie) {
				}
			}
		}
	}

	public void m2() {
		synchronized (this) {
			int i = 10;
			while (i-- > 0) {
				System.out.println(Thread.currentThread().getName() + " : " + i);
				try {
					Thread.sleep(500);
				} catch (InterruptedException ie) {
				}
			}
		}
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		final Thread3 myt3 = new Thread3();
		Thread t1 = new Thread(new Runnable() {
			public void run() {
				myt3.m1();
			}
		}, "t1");
		Thread t2 = new Thread(new Runnable() {
			public void run() {
				myt3.m2();
			}
		}, "t2");
		t1.start();
		t2.start();
	}

}



输出:

t1 : 9
t1 : 8
t1 : 7
t1 : 6
t1 : 5
t1 : 4
t1 : 3
t1 : 2
t1 : 1
t1 : 0
t2 : 9
t2 : 8
t2 : 7
t2 : 6
t2 : 5
t2 : 4
t2 : 3
t2 : 2
t2 : 1
t2 : 0



可以看出,当一个线程运行同步代码块时,另一个线程不能同时运行同步代码块。


程序4:

package testsynchronized;

public class Thread4 {
	public void m1() {
		synchronized (this) {
			int i = 5;
			while (i-- > 0) {
				System.out.println(Thread.currentThread().getName() + " : " + i);
				try {
					Thread.sleep(3000);
				} catch (InterruptedException ie) {
				}
			}
		}
	}

	public synchronized void m2() {
		int i = 5;
		while (i-- > 0) {
			System.out.println(Thread.currentThread().getName() + " : " + i);
			try {
				Thread.sleep(1000);
			} catch (InterruptedException ie) {
			}
		}
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		final Thread4 myt4 = new Thread4();
		Thread t1 = new Thread(new Runnable() {
			public void run() {
				myt4.m1();
			}
		}, "t1");
		Thread t2 = new Thread(new Runnable() {
			public void run() {
				myt4.m2();
			}
		}, "t2");
		t1.start();
		t2.start();
	}

}



输出:

t1 : 4
t1 : 3
t1 : 2
t1 : 1
t1 : 0
t2 : 4
t2 : 3
t2 : 2
t2 : 1
t2 : 0



可以看出,当一个线程运行同步代码块时,另一个线程就不能同时运行同步方法。


程序5:

package testsynchronized;

public class Thread5 {
	class Inner {
		private void m1() {
			int i = 5;
			while (i-- > 0) {
				System.out.println(Thread.currentThread().getName() + " : Inner.m4t1()=" + i);
				try {
					Thread.sleep(500);
				} catch (InterruptedException ie) {
				}
			}
		}

		private void m2() {
			int i = 5;
			while (i-- > 0) {
				System.out.println(Thread.currentThread().getName() + " : Inner.m4t2()=" + i);
				try {
					Thread.sleep(500);
				} catch (InterruptedException ie) {
				}
			}
		}
	}

	private void m1(Inner inner) {
		synchronized (inner) { // 使用对象锁
			inner.m1();
		}
	}

	private void m2(Inner inner) {
		inner.m2();
	}

	public static void main(String[] args) {
		final Thread5 myt5 = new Thread5();
		final Inner inner = myt5.new Inner();
		Thread t1 = new Thread(new Runnable() {
			public void run() {
				myt5.m1(inner);
			}
		}, "t1");
		Thread t2 = new Thread(new Runnable() {
			public void run() {
				myt5.m2(inner);
			}
		}, "t2");
		t1.start();
		t2.start();
	}
}



输出:

t1 : Inner.m4t1()=4
t2 : Inner.m4t2()=4
t1 : Inner.m4t1()=3
t2 : Inner.m4t2()=3
t1 : Inner.m4t1()=2
t2 : Inner.m4t2()=2
t1 : Inner.m4t1()=1
t2 : Inner.m4t2()=1
t1 : Inner.m4t1()=0
t2 : Inner.m4t2()=0



可以看到,当使用同步代码块时,并非要this,其他对象也可以,而且另一个线程可以同时运行飞同步代码块。


总结


使用synchronized就相当于取得了某个锁,如果是多线程,最多只有一个线程能运行同步方法,但是对于非同步方法,其他线程也能同时运行。


对于下面的代码:

package testsynchronized;

public class Thread6 {
	private boolean a;
	private boolean b;

	public void setA(boolean a) {
		this.a = a;
	}

	public void setB(boolean b) {
		this.b = b;
	}
	
	public synchronized void setSA(boolean a) {
		this.a = a;
	}

	public synchronized void setSB(boolean b) {
		this.b = b;
	}
	
	public void setAB() {
		setSA(true);
		setSB(false);
	}
	
	public synchronized void setSAB() {
		setA(false);
		setB(true);
	}
	
	public void check() {
		System.out.println(a == b);
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		final Thread6 myt6 = new Thread6();
		Thread t1 = new Thread(new Runnable() {
			
			@Override
			public void run() {
				myt6.setSAB();
				myt6.check();
			}
		}, "t1");
		Thread t2 = new Thread(new Runnable() {
			
			@Override
			public void run() {
				myt6.setA(true);
				myt6.setB(true);
			}
		}, "t2");
		t1.start();
		t2.start();
	}

}




是否会输出true。

理论上是有可能输出true的,因为两个线程,分别调用同步方法和非同步方法。为了输出true,可以加些代码:

public static void main(String[] args) {
		final Thread6 myt6 = new Thread6();
		Thread t1 = new Thread(new Runnable() {
			
			@Override
			public void run() {
				myt6.setSAB();
				try {
					Thread.sleep(1);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				myt6.check();
			}
		}, "t1");
		Thread t2 = new Thread(new Runnable() {
			
			@Override
			public void run() {
				myt6.setA(true);
				myt6.setB(true);
			}
		}, "t2");
		t1.start();
		t2.start();
	}



这样就输出true了。