Java 同步综合指南
已发表: 2022-05-20在我们解释Java 中的同步之前,我们必须简要回顾一下多线程的概念。 Java 的多线程特性允许同时执行程序的两个或多个部分,以最大限度地利用 CPU。 这样一个程序的每一部分都是一个线程,线程是一个进程中的轻量级进程。
现在,一个程序的多个线程可能会尝试访问相同的资源并产生不准确的结果。 因此,必须有一些同步来确保在给定的时间点只有一个线程可以访问资源。
这篇关于什么是 Java 同步的指南将通过示例详细探讨同步的概念。
Java中的同步是什么?
Java 同步是控制多个线程对共享资源的访问的能力。 当多线程 Java 程序尝试访问同一资源并产生错误结果时,它很有用。 使用 Java 同步功能,在给定时间点只有单个线程可以访问资源。
Java 提供了一种使用同步块同步线程任务的方法,这些同步块在同一对象上同步,并且一次只能在其中执行一个线程。 这些块用 synchronized 关键字标记,阻止任何其他试图进入同步块的线程,直到已经在块内的线程结束执行并离开块。
编写同步块的语法
在 Java 中编写同步块的一般语法如下:
同步(锁定对象)
{
// 同步语句
}
在上面的语法中, lockObject是指一个对象,其锁与同步元素相关。 现在,这将我们带到 Java 中的锁概念。
Java中的锁
Java 中的同步是围绕锁或监视器构建的。 每个对象都有一个关联的锁。 理想情况下,需要访问对象字段的线程必须首先获得对象的锁。 锁是一种比同步块更复杂、更灵活的线程同步机制。 它在包含大量锁实现的 java.util.concurrent.lock 包中定义。
从世界顶级大学学习在线软件开发课程。 获得行政 PG 课程、高级证书课程或硕士课程,以加快您的职业生涯。
Java同步方法
Java 同步方法的目的是为共享资源锁定对象。 因此,当线程调用同步方法时,该方法会自动获取该对象的锁,并在线程执行其作业时释放它。
下面是一个 Java 同步方法的示例:
//java同步方法的例子
类表{
synchronized void printTable(int n){//同步方法
for(int i=1;i<=5;i++){
System.out.println(n*i);
尝试{
线程.sleep(400);
}catch(Exception e){System.out.println(e);}
}
}
}
MyThread1 类扩展 Thread{
药片;
MyThread1(表 t){
这.t=t;
}
公共无效运行(){
t.printTable(5);
}
}
MyThread2 类扩展 Thread{
药片;
MyThread2(表 t){
这.t=t;
}
公共无效运行(){
t.printTable(100);
}
}
公共类TestSynchronization2{
公共静态无效主要(字符串参数[]){
Table obj = new Table();//只有一个对象
MyThread1 t1=new MyThread1(obj);
MyThread2 t2=new MyThread2(obj);
t1.start();
t2.start();
}
}
输出:
5
10
15
20
25
100
200
300
400
500
没有同步会发生什么?
现在,让我们看看前面没有同步的程序(注意没有 synchronized 关键字)。
类表{
void printTable(int n){//方法不同步
for(int i=1;i<=5;i++){
System.out.println(n*i);
尝试{
线程.sleep(400);
}catch(Exception e){System.out.println(e);}
}
}
}
MyThread1 类扩展 Thread{
药片;
MyThread1(表 t){
这.t=t;
}
公共无效运行(){
t.printTable(5);
}
}
MyThread2 类扩展 Thread{
药片;
MyThread2(表 t){
这.t=t;
}
公共无效运行(){
t.printTable(100);
}
}
类 TestSynchronization1{
公共静态无效主要(字符串参数[]){
Table obj = new Table();//只有一个对象
MyThread1 t1=new MyThread1(obj);
MyThread2 t2=new MyThread2(obj);
t1.start();
t2.start();
}
}
输出:
5
100
10
200
15
300
20
400
25
500
如您所见,没有同步,输出是不一致的。
探索我们流行的软件工程课程
SL。 不 | 软件开发计划 | |
1 | LJMU & IIITB 计算机科学硕士 | 加州理工学院 CTME 网络安全证书课程 |
2 | 全栈开发训练营 | 区块链中的 PG 程序 |
3 | 软件开发行政研究生课程 - DevOps 专业化 | 查看所有软件工程课程 |
Java中的同步类型
要回答什么是 Java 中的线程同步,我们有两种可用的同步类型:线程同步和进程同步。
让我们了解每个含义。
线程同步:当多个线程试图访问一个共享资源时,我们必须确保该资源一次只被一个线程使用。 线程同步是当多个线程试图同时使用共享资源时,只允许一个线程使用共享资源的过程。
进程同步:指多个进程同时执行,以达到进程提交到适当的执行顺序的状态。 当两个或多个进程协作时,需要进程同步,并且一个进程的执行会影响另一个进程。 因此,进程同步消除了输出不准确的可能性并保证了正确的执行顺序。
Java中的同步方法
概括地说,Java 中有四种同步方法:
- 同步的静态方法
- 同步实例方法
- 静态方法中的同步块
- 实例方法内的同步块
让我们更详细地了解 Java 同步的每种方法。
同步的静态方法
在这里,我们使用 synchronized 关键字来标记 Java 中的静态方法。 下面是一个 Java 同步静态方法的示例:
公共静态 MyStaticCounter {
私有静态int计数= 0;
公共静态同步无效增量(整数值){
计数 += 值;
}
}
同步实例方法
当使用带有实例方法的同步块时,每个对象都有其同步方法。 每个对象只能有一个可以在方法内部执行的线程。 如果有多个对象,则可以为块内的每个对象执行单个线程。
公共类 MyCounter {
私人int计数= 0;
公共同步无效增量(整数值){
this.count += 值;
}
公共同步无效减量(整数值){
this.count -= 值;
}
}
静态方法中的同步块
下面是我们在静态方法中使用同步块的示例:
公共类 MyClass {
公共静态无效打印(字符串消息){
同步(MyClass.class){
log.writeln(消息);
}
}
}
实例方法内的同步块
我们可以在方法中的特定块上使用同步,而不是同步整个方法。 下面是一个非同步方法中的同步代码块示例:
公共无效增量(整数值){
同步(这个){
this.count += 值;
}
}
Java 中的同步需求
既然您知道什么是 Java 中的同步,您可能想知道我们为什么首先使用它。
Java synchronized 关键字提供了并发编程所必需的功能。 以下是 Java 中的同步如何提供帮助:
- Java 同步提供了锁定功能来消除线程之间的任何竞争条件并确保对共享资源的互斥访问。
- Java 同步锁定同时提供锁定和解锁功能。 因此,线程需要在进入同步方法或块之前获取锁。
- synchronized 关键字防止编译器对程序语句重新排序。
结论
总而言之,Java 中的同步确保一次只有一个线程可以访问共享资源。 我们可以使用 Java synchronized 关键字使块或方法同步。 当一个线程想要进入一个同步块时,它必须获得一个锁,离开这个块后,线程释放锁。 我们可以在方法中或在方法块中使用 synchronized 关键字。
想知道在哪里学习 Java?
upGrad 的软件工程与工作相关的 PG 认证 就是你要找的!
upGrad 的软件工程与工作相关的 PG 认证专为应届毕业生和最后几年设计,非常适合那些想要学习编程并担任入门级软件角色的人。 这个为期 5 个月的在线课程将教授 Java、JavaScript、HTML5、DSA、AWS、MERN 等顶级软件技能!
问:为什么我们在 Java 中使用同步?
A:Java 中的 synchronized 关键字确保一次只有一个线程可以访问共享资源。 当多线程 Java 程序尝试访问相同的资源并产生不准确的结果时,它很有用。
问:Java 中的同步是如何实现的?
答:Java 使用监视器的概念实现同步,在给定时间只有一个线程拥有监视器。 当一个线程获得锁时,它可以访问监视器,并且所有其他试图进入锁定监视器的线程保持阻塞,直到第一个线程离开监视器。
问:Java 中的死锁是什么?
A:Java 死锁发生在一个线程正在等待对象锁,但另一个线程获取它,而第二个线程正在等待第一个线程获取的对象锁。 因此,两个线程都在等待对方释放锁,从而导致死锁。