【问题标题】:Access synchronized method from another thread using same instance使用同一实例从另一个线程访问同步方法
【发布时间】:2016-03-06 14:45:58
【问题描述】:

我的项目中有一个核心方法,我需要它是synchronized,以免同时被访问两次,因此我有一个线程使用这个类的实例来访问这个方法,但在这个线程中,我需要有一个长寿命循环来访问具有固定值的相同方法,所以我必须使用另一个线程才能让第一个线程继续前进并完成它的职责,但可以肯定该方法不会使用第一个线程中使用的相同实例从第二个线程运行,并且不知何故我无法从该类中实例化另一个实例,因为我必须完全使用这个实例,所以如何克服这个问题。

下面是翻译成java的问题:

public class ClassOne {
    synchronized public void my_method(int number) {
        // Do some Work
    }
}

public class ClassTwo {

    private void some_method() {
        Thread one = new Thread(new Runnable() {
            @Override
            public void run() {
                ClassOne class_one = new ClassOne();
                // DO Work
                class_one.my_method(0);
                run_loop(class_one);
                // Complete Work
            }
        });
        one.start();
    }

    boolean running = true;

    private void run_loop(final ClassOne class_one) {
        Thread two = new Thread(new Runnable() {

            @Override
            public void run() {
                while (running) {
                    class_one.my_method(1); // won't run
                    Thread.sleep(10000);
                }
            }
        });
        two.start();
    }

}

实际问题概述:

  • my_method ---> 是发送UDP包。
  • 该方法必须同步,否则当我尝试多次重复使用它时,我会得到 socket is already open 异常。
  • 在某些时候,我必须每 10 秒重复发送一个 KeepAlive 消息,因此,我必须为 run_loop 方法中的线程 two 启动一个单独的线程。

【问题讨论】:

  • 在您的描述中,请参考您在代码中提供的实际方法,任何愿意帮助的人都会更容易
  • "// won't run" 你不是说不会编译吗? AFAIK,这里没有定义 class_one
  • 由于Thread.sleep 中的未处理异常,它无法编译。 OP,恐怕您没有在代码中提供有意义的示例
  • 线程二中的调用没有理由阻塞,因为线程一对该方法的调用在线程二开始之前就已经返回。修复编译错误并运行贴出的代码显示my_method被重复调用。
  • @LuigiCortese 实际方法会使代码对其他人模糊,我已尽力通过此代码使想法清晰。并且不要关注未处理的异常,因为所有异常都在主代码中处理。您还可以查看解释问题概述的问题的补充内容。

标签: java multithreading synchronized data-synchronization


【解决方案1】:

放置一些可以编译和工作的东西。我不明白为什么您需要同步此功能。检查此程序的输出...仅当第一个线程完成访问后,第二个线程才访问此方法(除非您错过了添加一些额外的代码)。

class ClassOne {    
   int criticalData = 1;
   synchronized public void my_method(int number) {
     // Do some Work
     criticalData *= 31;
     System.out.println("Critical data:" + criticalData + "[" + Thread.currentThread().getName() + "]");
   }
 }

类 ClassTwo { 布尔运行 = true;

  public void some_method() {

    Thread one = new Thread(new Runnable() {
        public void run() {
            ClassOne class_one = new ClassOne();
            // DO Work
            class_one.my_method(0);
            run_loop(class_one);
            // Complete Work
        }
    });
    one.start();
}

public void run_loop(final ClassOne class_one) {
     Thread two = new Thread(new Runnable() {

        public void run() {
            while (running) {
                class_one.my_method(1); // won't run
                 try {
                    Thread.sleep(10000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
             }
         }
     });
     two.start();
   }
}

 public class StackExchangeProblem {
   public static void main(String[] args) {
     ClassTwo two = new ClassTwo();
     two.some_method();
   }
 }

【讨论】:

  • 函数必须同步,这是我实际代码中的逻辑。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多