ARTS Share3 Java中的Synchronized

多线程程序经常会遇到一种问题,就是当多个线程试图访问同一个资源的时候,最后会产生不可预料的结果。因此,需要使用一些同步的措施来保证在一个给定的时间点只有一个线程可以来访问这个资源。

Java提供了一种使用synchronized块创建线程和同步其任务的方法。 Java中的同步块使用synchronized关键字标记。 Java中的同步块在某个对象上同步。 在同一对象上同步的所有同步块一次只能在其中执行一个线程。 尝试进入同步块的所有其他线程都被阻塞,直到同步块内的线程退出块。

以下是同步块的一般形式:

//一次只能执行一个线程。sync_object是对象的引用,其锁定与监视器关联。代码被称为同步,监视器对象
synchronized(sync_object){
   // Access shared variables and other
   // shared resources
}

此同步在Java中使用称为监视器的概念实现。 在给定时间只有一个线程可以拥有监视器。 当线程获得锁定时,据说它已进入监视器。 尝试进入锁定监视器的所有其他线程将被挂起,直到第一个线程退出监视器。


import java.io.*; 
import java.util.*; 

class Sender { 
	public void send(String msg) { 
		System.out.println("Sending\t" + msg ); 
		try{ 
			Thread.sleep(1000); 
		} catch (Exception e) { 
			System.out.println("Thread interrupted."); 
		} 
		System.out.println("\n" + msg + "Sent"); 
	} 
} 


class ThreadedSend extends Thread { 
	private String msg; 
	private Thread t; 
	Sender sender; 
	ThreadedSend(String m, Sender obj) { 
		msg = m; 
		sender = obj; 
	} 

	public void run() { 
		**synchronized(sender)** { 
			sender.send(msg); 
		} 
	} 
} 

class SyncDemo { 
	public static void main(String args[]) 
	{ 
		Sender snd = new Sender(); 
		ThreadedSend S1 = 
			new ThreadedSend( " Hi " , snd ); 
		ThreadedSend S2 = 
			new ThreadedSend( " Bye " , snd ); 
		S1.start(); 
		S2.start(); 
		try{ 
			S1.join(); 
			S2.join(); 
		} catch(Exception e) { 
			System.out.println("Interrupted"); 
		} 
	} 
} 

Sending     Hi 

 Hi Sent
Sending     Bye 

 Bye Sent

每次运行程序时输出都是相同的。

在上面的示例中,我们选择在ThreadedSend类的run()方法内同步Sender对象。 或者,我们可以将整个send()块定义为synchronized,它将产生相同的结果。 然后我们不必在ThreadedSend类中的run()方法内同步Message对象

class Sender { 
	public synchronized void send(String msg) { 
		System.out.println("Sending\t" + msg ); 
		try{ 
			Thread.sleep(1000); 
		} catch (Exception e) { 
			System.out.println("Thread interrupted."); 
		} 
		System.out.println("\n" + msg + "Sent"); 
	} 
} 

我们并不总是需要同步整个方法。 有时最好只同步方法的一部分。 方法中的Java同步块使这成为可能。

class Sender { 
	public void send(String msg) { 
		synchronized(this) { 
			System.out.println("Sending\t" + msg ); 
			try{ 
				Thread.sleep(1000); 
			} catch (Exception e) { 
				System.out.println("Thread interrupted."); 
			} 
			System.out.println("\n" + msg + "Sent"); 
		} 
	} 
} 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值