这里需要同步

发布于 2024-08-13 19:53:32 字数 1486 浏览 3 评论 0原文

我有一个java小程序。该小程序内的一个类正在创建一个线程来执行某些工作,等待 30 秒才能完成该工作,如果在 30 秒内未完成,则会设置一个布尔值来停止该线程。等待和布尔值更改位于同步块中,考虑到除了这两个线程之外没有其他线程在运行,这是必要的吗?

    System.out.println("Begin Start Session");
    _sessionThread = new SessionThread();
    _sessionThread.start();

    synchronized (_sessionThread)
    {
        _sessionThread.wait(30000);
        _sessionThread._stopStartSession = true;
    }

为什么我不能这样做。

    System.out.println("Begin Start Session");
    _sessionThread = new SessionThread();
    _sessionThread.start();

    _sessionThread.wait(30000);
    _sessionThread._stopStartSession = true;

SessionThread运行方法。调用 JNI 方法来调用 dll 以打开程序窗口。

public void run()
{
    try
    {
        startExtraSession();
    } 
    catch (Throwable t)
    {
        t.printStackTrace();
    }
        notify();
}


private native void openSessionWindow(String session_file);

private void startExtraSession()
{
    final String method_name = "startExtraSession";

    String title = _sessionInfo._title;
    long hwnd = 0;

    openSessionWindow(_sessionInfo._configFile);

    try
    {
        //Look for a window with the predefined title name...
        while ((hwnd = nativeFindWindow(title)) == 0 && !_stopStartSession)
        {
            Thread.sleep(500);
    }
    }
    catch(Throwable t)
    {
       t.printStackTrace();
    }
}

1.真的需要同步吗?
2.除了使用线程之外,还有更好的方法来完成此任务吗?

I have a java applet. A class inside that applet is creating a thread to do some work, waiting 30 seconds for that work to complete, if its not completed in 30 secs it sets a Boolean to stop the thread. The wait and Boolean change are in a synchronized block, Is this necessary considering there is no other thread running aside from these 2.

    System.out.println("Begin Start Session");
    _sessionThread = new SessionThread();
    _sessionThread.start();

    synchronized (_sessionThread)
    {
        _sessionThread.wait(30000);
        _sessionThread._stopStartSession = true;
    }

Why couldn't I just do this instead.

    System.out.println("Begin Start Session");
    _sessionThread = new SessionThread();
    _sessionThread.start();

    _sessionThread.wait(30000);
    _sessionThread._stopStartSession = true;

SessionThread run method. Invokes a JNI method to call a dll to open a program window.

public void run()
{
    try
    {
        startExtraSession();
    } 
    catch (Throwable t)
    {
        t.printStackTrace();
    }
        notify();
}


private native void openSessionWindow(String session_file);

private void startExtraSession()
{
    final String method_name = "startExtraSession";

    String title = _sessionInfo._title;
    long hwnd = 0;

    openSessionWindow(_sessionInfo._configFile);

    try
    {
        //Look for a window with the predefined title name...
        while ((hwnd = nativeFindWindow(title)) == 0 && !_stopStartSession)
        {
            Thread.sleep(500);
    }
    }
    catch(Throwable t)
    {
       t.printStackTrace();
    }
}

1. Is the synchronized really needed?


2. Is there a better way to accomplish this aside from using threads?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

明媚如初 2024-08-20 19:53:32

给定线程需要拥有对象上的锁才能对其调用 wait(long)。这是通过在所述对象上使用同步块来实现的。

请参阅 J2SE 规范 使用wait

在 java 中获取锁/监视器可以通过多种方式完成:

  • 同步(非静态)方法中,线程在 this 引用的对象上拥有一个监视器。
  • 静态同步方法中,线程在定义所述方法的类的Class描述符上拥有一个监视器。
  • synchronized(x) 块中,线程拥有 x 上的监视器。

如果满足以下条件,该锁将被释放:

  • 您到达同步代码块之外(无论是方法、静态方法还是显式块)。
  • 您已调用 wait() 或其变体之一(并且您将在该方法返回之前重新获取它)。

这两个列表都可能省略特定案例,但至少应涵盖大部分典型用例。

A given thread is required to own a lock on a object to be able to call wait(long) on it. This is achieved by using a synchronized block on the said object.

See J2SE specification on using wait.

Acquiring a lock/monitor in java can be done in various ways:

  • In a synchronized (non-static) method, the thread owns a monitor on the object referenced by this.
  • In a static synchronized method, the thread owns a monitor on the Class<?> descriptor for the class that defines the said method.
  • In a synchronized(x) block, the thread owns a monitor on x.

That lock will be released if:

  • You get outside of the synchronized code block (be it a method, static method, or explicit block).
  • You have called wait() or one of its variations (and you'll re-acquire it just before the method returns).

Both these two lists may omit specific cases but should cover at least a large portion of the typical use cases.

神回复 2024-08-20 19:53:32

您能发布 SessionThread 代码吗?如果不拥有锁就无法等待,所以需要synchronized(_sessionThread)来执行_sessionThread.wait(30000);不确定 _sessionThread._stopStartSession = true; 是怎么回事;

Can you please post SessionThread code? You cannot wait if you don't own the lock, so you need synchronized (_sessionThread) to do _sessionThread.wait(30000); Not sure what's with _sessionThread._stopStartSession = true;

浅忆 2024-08-20 19:53:32

有一个非常简单的原因,您需要 synchronized 来调用 wait

synchronized 确保没有人调用 notify 或在调用 wait 的同时 notifyAll

例如:线程 1

synchronized( obj )
{
    triggerActionOnThread2();
    obj.wait();
}

线程 2(由triggerActionOnThread2 触发)

    ...
    synchronized( obj )
    {
        obj.notify();
    }

如果您没有同步块,则 notify 可能发生在 wait 之前(或期间),然后 wait 错过了 notify,并且您可以挂起线程1.

想象一下上面的代码块没有 synchronized 块,并想象如果在 wait 被调用之前线程 2 通过notify一直执行。

顺便说一句,当 Java 工程师的工作涉及多线程编程时,我在面试时就问了这个问题。

There's a very simple reason that you need synchronized to call wait

The synchronized makes sure that nobody is calling notify or notifyAll at the same time you're calling wait

For example: Thread 1

synchronized( obj )
{
    triggerActionOnThread2();
    obj.wait();
}

Thread 2 (triggered by triggerActionOnThread2)

    ...
    synchronized( obj )
    {
        obj.notify();
    }

If you don't have the synchronized blocks, then the notify might happen before (or during) the wait, and then the wait misses the notify, and you can hang Thread 1.

Imagine the above blocks of code without the synchronized blocks, and imagine if Thread 2 is executed all the way through the notify before the wait gets called.

BTW, I ask this very question on interviews for Java engineers when the job will involve multithreaded programming.

审判长 2024-08-20 19:53:32

如果布尔值是线程之间唯一的共享状态,则声明布尔瞬态将保证在线程之间看到对其所做的更改,就像围绕布尔值访问的同步块一样。

If the boolean is the only shared state between the threads, declaring the boolean transient will guarantee that changes to it are seen between the threads as would a synchronization block around access to the boolean.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文