ARTS Share3 Java中的Synchronized

news/2024/5/17 18:15:30 标签: java, 多线程, thread, 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"); 
		} 
	} 
} 


http://www.niftyadmin.cn/n/749092.html

相关文章

《深入浅出话数据结构》系列之什么是B树、B+树?为什么二叉查找树不行?

本文将为大家介绍B树和B树,首先介绍了B树的应用场景,为什么需要B树;然后介绍了B树的查询和插入过程;最后谈了B树针对B树的改进。 在谈B树之前,先说一下B树所针对的应用场景。那么B树是用来做什么的呢? B树是…

ARTS Review4 Here’s What You Can Learn in 10 Minutes

文章链接:http://blog.thefirehoseproject.com/posts/10-minutes-learn-programming/ 这是你在10分钟内可以学到的东西 1.使用google进行查找,解决问题,google的关键字应该是基于你对于异常出现地方的代码的理解的基础上你抽取出来的&#…

【DPDK】【ring】从DPDK的ring来看x86无锁队列的实现

【前言】 队列是众多数据结构中最常见的一种之一。曾经有人和我说过这么一句话,叫做“程序等于数据结构算法”。因此在设计模块、写代码时,队列常常作为一个很常见的结构出现在模块设计中。DPDK不仅是一个加速网络IO的框架,其内部还提供众多的…

vue基础中的注意事项,以及一些学习心得

vue中你不知道的东西、以及注意事项 不格小说 www.vbuge.com v-html使用 v-html的时候该指令中的值会覆盖绑定标签中原有的值,且使用v-html的时候不要将他设置为给用户提供内容的地方,因为v-html很容易被XSS攻击v-bind 使用v-bind绑定属性值为布尔值的属…

ARTS Tip4 form的submit和ajax提交

说一下ajax提交和form.submit提交: post是一种HTTP动作,它是一种关于客户端和服务端如何沟通的HTTP的协议。 HTML使用FORM的概念定义客户端语法。HTML实现通常假设HTTP协议,并且已经定义了与服务器的FORM交互是使用HTTP POST操作进行的&…

ARTS Share4 mysql中autocommit

MySQL中的事务(自动提交,显示和隐式),在MySQL中事务控制数据操作语句以确保它们是原子的。什么叫做原子的,也就是说这个事务要么成功,要么失败。 什么时候算事务成功或者失败? 当向数据库事务…

谈谈Java的Collection接口

目录 谈谈Collection前言Collection方法1.boolean add(E)2.void clear()3.boolean contains(Object o)4.boolean isEmpty()5.Iterator iterator()6.int size()7.Boolean remove()总结什么是可选操作集合使用的整体框架(步骤)谈谈Collection石头文学 http…

ARTS Share5 Java数组

数组: 在Java中,数组是用来存储一组数据类型相同的变量的值,这些变量共用一个变量名。Java中的数组可以是一维数组也可以是多维数组,其中一维数组使用的频率比较高。 一维数组: 一维数组的声明: type a…