gpt4 book ai didi

java - 同一线程能够在同一对象上执行两个同步方法

转载 作者:行者123 更新时间:2023-12-01 18:25:28 24 4
gpt4 key购买 nike

据我所知,只有一个线程可以在同一 block 上的同步方法上执行,但在下面的生产者消费者问题中,我可以运行这两种方法。

示例代码

import java.util.concurrent.CountDownLatch;

public class VIV {

public static void main(String[] args) throws Exception {
Number no = new Number();

//Same Object is passed
Even ev = new Even(no, 10);
Odd od = new Odd(no, 10);

Thread oddThraed = new Thread(od,"ODD");
oddThraed.start();

Thread evenThraed = new Thread(ev,"Even");
evenThraed.start();
}
}

class Number {

int no;
boolean flag=false;

public synchronized int getEvenNo() {
System.out.println("In Even Method");
// wait block so no other thread can enter on same object synchronized method
try{
wait();
}catch (Exception e) {
// TODO: handle exception
}

if(!flag) {
try {
Thread.sleep(1000);
}catch (Exception e) {
// TODO: handle exception
}
}

no=no+1;
System.out.println(Thread.currentThread().getName()+":"+no);
flag=false;
notify();
return no;
}

public synchronized int getOddNo() {
System.out.println("In ODD Method");
// wait block so no other thread can enter on same object synchronized method
try{
wait();
}catch (Exception e) {
// TODO: handle exception
}

if(flag) {
try{
wait();
}catch (Exception e) {
// TODO: handle exception
}
}
no = no+1;
System.out.println(Thread.currentThread().getName()+":"+no);
flag=true;
notify();
return no;
}

}

class Even implements Runnable {
Number num;
int noOfTime;

Even(Number no, int noOfTime) {
this.num=no;
this.noOfTime=noOfTime;
}

public void run() {
for(int i=0;i<noOfTime;i++) {
num.getEvenNo();
}
}
}

class Odd implements Runnable {

Number num;
int noOfTime;

Odd(Number no, int noOfTime) {
this.num=no;
this.noOfTime=noOfTime;
}

public void run() {
for(int i=0;i<noOfTime;i++) {
num.getOddNo();
}
}
}

输出:

  1. 采用奇数方法
  2. 偶数法

As 仅创建一个 Number 对象并将其传递给调用其两个不同同步方法的其他类。两种方法都会在等待后打印消息。

最佳答案

两个方法同时执行的原因是 wait() 方法释放锁。一旦您的 synchronized 方法调用 wait(),锁就会被返还,并且另一个线程可以调用同一对象上的另一个 synchronized 方法。不要以这种方式在 synchronized 方法内调用 wait()!

wait() 调用也是导致死锁的原因。这就是正在发生的事情:

  1. odd 方法获取锁并开始执行。
  2. odd 方法打印其第一条消息。
  3. odd 方法调用 wait(),它会释放锁并等待收到通知。
  4. even 方法现在可以获取已释放的锁。
  5. even 方法打印其第一条消息。
  6. even 方法调用 wait(),后者释放锁并等待收到通知。

此时,您已处于两个 synchronized 方法的中间(因为 wait() 释放了锁),并且陷入了死锁(因为这两个方法正在等待)。

不要调用wait(),除非您非常确定这就是您所需要的。如果您的 wait() 只是让它等待,看看同步是否可以被破坏,您可以尝试 Thread.sleep() ,这将暂停而不释放任何锁。通常,将相关方法或 block 声明为“同步”就足够了,无需任何“等待”/“通知”。

(顺便说一句,拥有一个名为 Number 的类并不是一个好主意,因为这是一个标准的 JDK 类。它是 Double 的父类(super class),整数,依此类推。)

关于java - 同一线程能够在同一对象上执行两个同步方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26361367/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com