简体   繁体   English

如何在Java中控制对对象的多线程访问?

[英]how to control multi thread access to the object in java?

i am writing server in java. 我正在用Java编写服务器。 for purpose of this question lets say the following: server can accept multiple clients, each one in its own thread. 出于这个问题的目的,我们可以这样说:服务器可以接受多个客户端,每个客户端在其自己的线程中。 each client once connected calls one method on the server which draws some graphic object. 连接后的每个客户端都会调用服务器上的一个方法来绘制一些图形对象。 only one instance of the method must be active at once. 该方法只有一个实例必须一次处于活动状态。 in case this method is active at the same time at multiple threads, the result will be that drawn object would be scrambled. 如果此方法在多个线程上同时处于活动状态,则结果将是扰乱了绘制的对象。 it takes around 100ms for method to execute. 方法执行大约需要100毫秒。 to prevent multiple threads from accessing the method at once, i added static field of the class which once this method is called is updated to mark that method is active, and once method completes it updates the property to mark that method is inactive. 为了防止多个线程一次访问该方法,我添加了该类的静态字段,该类的静态字段将在调用此方法后更新以标记该方法为活动状态,并且一旦方法完成,它将更新属性以标记该方法为非活动状态。 each thread calls this method, but first thing method does is check the value of that field, and if it indicates that another instance of the method is already executing, it puts this thread to sleep for short time, and once it wakes up, it periodically checks the value of the field, and once value indicates another thread is complete executing this method, then another thread continues, updates the value of this field to indicate it is executing and then executes, and again updates it to indicate it finished executing. 每个线程都调用此方法,但是方法的第一件事是检查该字段的值,如果它指示该方法的另一个实例已在执行,则它将使该线程休眠一小段时间,一旦唤醒,它将定期检查该字段的值,一旦该值指示另一个线程已完成执行该方法,然后另一个线程继续执行,则更新该字段的值以指示它正在执行,然后执行,然后再次更新它以指示其完成执行。 this goes for each thread once it calls the method. 调用该方法的每个线程都可以使用。

this approach improved cases where collision occurs, but it did not eliminated it completely. 这种方法改善了发生碰撞的情况,但是并没有完全消除它。 this is because it takes time since some thread detects that another thread is finished executing until it updates the parameter to indicate that it is now executing again. 这是因为某个线程检测到另一个线程已完成执行,直到它更新参数以指示它现在再次执行为止,这需要时间。 this time is very short, less than a 1ms, but still it is possible for collision to occur, that is for more than one thread to detect that method is not executing. 这个时间非常短,少于1ms,但是仍然有可能发生冲突,即有多个线程检测到该方法没有执行。 since it is possible that since one thread detects method is not executing until it marks it as executing that in the mean time another thread also detects this method as not executing. 因为有可能一个线程检测到该方法未执行,直到它标记为正在执行该方法,与此同时,另一个线程也检测到该方法未执行。

i know this might seam confusing, so i prepared a small example for you to understand me better: 我知道这可能会造成混乱,所以我准备了一个小例子供您更好地理解我:

public class some_class_acessed_by_multiple_threads
{
    private static volatile java.lang.Boolean lock_access;
    static 
    {
        lock_access = false;
    }
    public static void some_method_called_by_multiple_threads() throws java.lang.InterruptedException
    {
        //detection.
        while(lock_access)
        {
            java.lang.Thread.sleep(64);
        }
        //locking access to other threads.
        lock_access =true;
        some_method_which_must_not_be_active_in_multiple_threads_at_once();
        //once execution completes, unlocking access to other threads.
        lock_access =false;
    }
    private static void some_method_which_must_not_be_active_in_multiple_threads_at_once()
    {
        //draw some object.
    }
}

if i use logic like in this example above to prevent access to method by more than one thread at once, it works great for small number of threads. 如果我使用上述示例中的逻辑来防止一次由多个线程访问方法,那么它适用于少量线程。 if 1, 2, 5, 10, 50 clients is connected, collisions not occur. 如果连接了1、2、5、10、50个客户端,则不会发生冲突。

but if i have lets say 1000 clients (what means 1000 threads fighting to access this method for drawing objects) or more, collisions still start to happen very often. 但是如果我可以说有1000个客户端(这意味着有1000个线程在争用这种方法来绘制对象),那么冲突仍然会经常发生。 as you can see from my example, from the time line "detection" finishes executing until the time line "locking access..." finishes executing, it passes some time. 从我的示例中可以看到,从时间轴“检测”完成执行到时间线“锁定访问...”完成执行,它要花费一些时间。 probably time in microseconds, but still some time passes. 时间可能以微秒为单位,但仍然需要一些时间。

so my question to you is, do you have any suggestions on how i can improve my code above, so that not even 1000 threads fighting for access to the method for drawing objects can cause collision? 所以我想问的是,您是否对我如何改进上述代码有任何建议,以至于甚至没有1000个线程在争用绘画对象方法的争用也不会引起冲突?

thank you for any suggestions. 感谢您的任何建议。

Have you tried the built-in synchronized java keyword? 您是否尝试过内置的synchronized Java关键字?

private static void some_method_which_must_not_be_active_in_multiple_threads_at_once()

becomes 变成

private static synchronized void some_method_which_must_not_be_active_in_multiple_threads_at_once()

This way, each thread has to kave a token to run this method. 这样,每个线程都必须拥有一个令牌才能运行此方法。 Tell us if it helps! 告诉我们是否有帮助!

you should use synchronization... simply synchronize the method 您应该使用同步...只需同步方法

public static synchronized void some_method_called_by_multiple_threads() throws java.lang.InterruptedException

synchronization simply means one thread can access the method at a time. 同步只是意味着一个线程可以一次访问该方法。 refer the API documentations for more details 请参阅API文档以获取更多详细信息

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM