Java多线程同步 – synchronized 用法

1.      利用类对象进行同步

 当两个线程访问同一个类对象时,发生竞争。同步加锁的是对象,而不是代码。

package thrds;

public class FiveThread {
	
	public static void main(String args[])
	{
		ThTst obj = new ThTst();
		Thread t1 = new Thread(obj);  // 两个线程用同一个对象,发生互斥(属于对象互斥)
		Thread t2 = new Thread(obj);
		
		t1.start();
		t2.start();
	}

}

class ThTst extends Thread {
	
	public void run() {
		tst();
	}
	
	synchronized void tst()
	{
		System.out.println(Thread.currentThread().getId() + " in");
		
		try {
			Thread.sleep(5000);
		} catch (InterruptedException e) {
					e.printStackTrace();
		}
		
		System.out.println(Thread.currentThread().getId() + " out");
	}
}

输出结果:
15 in
15 out
14 in
14 out

如果将上述 main函数中改为: 
Thread t1 = new Thread(new ThTst());  // 使用两个对象,不会发生竞争
Thread t2 = new Thread(new ThTst());

输出结果:
17 in
15 in
15 out
17 out


 

2.      使用类定义和 对象 进行同步(类.class)

即使两个线程分别访问不同的对象,也会发生竞争。加锁的是代码段。

因为一个类的类定义只有一个,因此,到加锁的地方,只能有一个线程进去执行。

注意:null不可用来作为同步对象。

 

package thrds;

public class SixThread {
	
	
	public static void main(String args[])
	{
		Thread t1 = new Thread(new ThTst2());
		Thread t2 = new Thread(new ThTst2());
		
		t1.start();
		t2.start();
	}

}

class ThTst2 extends Thread {
	
	private static Integer iObj = 9;
	
	public void run() {
		tst();
	}
	
	synchronized void tst()
	{
		synchronized (ThTst2.class) { //这里可用任何类类型,如 String.class, Integer.class  或使用 其他对象如iObj 也是一样的
			
			System.out.println(Thread.currentThread().getId() + " in");
			
			try {
				Thread.sleep(5000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			
			System.out.println(Thread.currentThread().getId() + " out");
		}
	}
}

输出结果:
14 in
14 out
16 in
16 out


3.      2中使用对象同步,用来同步的对象,可由参数传入。这样,可提供更多的灵活性,程序员可以控制哪几个线程竞争同一个对象。(在设计时可参考)

package thrds;

import org.omg.CORBA.INV_OBJREF;

public class SevenThread {
	
	
	public static void main(String args[])
	{
		ThTst3 tObj1 = new ThTst3();
		ThTst3 tObj2 = new ThTst3();
		
		String lock = new String("lock"); 
		tObj1.setLock(lock);
		tObj2.setLock(lock);
		
		Thread t1 = new Thread(tObj1);
		Thread t2 = new Thread(tObj2);
		
		t1.start();
		t2.start();
	}

}

class ThTst3 extends Thread {
	
	private String lock = null;
	
	@Override
	public void run() {
		tst();
	}
	
	synchronized void tst()
	{
		synchronized (lock) { //同步对象由参数传入
			
			System.out.println(Thread.currentThread().getId() + " in");
			
			try {
				Thread.sleep(5000);
			} catch (InterruptedException e) {
				// TODO 自动生成的 catch 块
				e.printStackTrace();
			}
			
			System.out.println(Thread.currentThread().getId() + " out");
		}
	}
	
	void setLock(String lock)
	{
		this.lock = lock;
	}
}

输出结果:
15 in
15 out
16 in
16 out




synchronized关键字,多线程在同步时,需要看用来同步的对象(包括类定义)是不是唯一的。只有对象是唯一的时候,才会发生互斥。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值