Home  >  Article  >  Backend Development  >  Thoughts on thread safety issues in singleton mode in PHP

Thoughts on thread safety issues in singleton mode in PHP

WBOY
WBOYOriginal
2023-10-15 10:14:01550browse

Thoughts on thread safety issues in singleton mode in PHP

Thinking about the thread safety of singleton mode in PHP

In PHP programming, the singleton mode is a commonly used design pattern, which can ensure that a class There is only one instance, and a global access point is provided to access this instance. However, when using the singleton pattern in a multi-threaded environment, thread safety issues need to be considered.

The most basic implementation of the singleton pattern includes a private constructor, a private static variable and a public static method. The specific code is as follows:

class Singleton
{
    private static $instance;

    private function __construct()
    {
        // 保证外部无法通过new关键字创建实例
    }

    public static function getInstance()
    {
        if (!isset(self::$instance)) {
            self::$instance = new self();
        }
        return self::$instance;
    }
}

In a single-threaded environment, the above code works very well. Each time the getInstance() method is called, it will check whether $instance is empty, and if it is empty, a new instance will be created. Otherwise, the existing instance is returned directly.

However, in a multi-threaded environment, there is the problem of concurrent access. When multiple threads call the getInstance() method at the same time, they may check that $instance is empty at the same time, and then create multiple instances at the same time. This defeats the purpose of the singleton pattern.

In order to solve the problem of thread safety, we can use locking to ensure that only one thread can create an instance. The specific code is as follows:

class Singleton
{
    private static $instance;

    private function __construct()
    {
        // 保证外部无法通过new关键字创建实例
    }

    public static function getInstance()
    {
        if (!isset(self::$instance)) {
            // 加锁
            synchronized(self::$instance) {
                if (!isset(self::$instance)) {
                    self::$instance = new self();
                }
            }
        }
        return self::$instance;
    }
}

In the above code, we introduced the synchronized keyword to wrap the code block that needs to be locked. This way, when one thread enters this code block, other threads will wait.

Although thread safety is ensured through locking, it also brings performance reduction. Because locking and unlocking operations are required every time the getInstance() method is called, this will increase the overhead of the program.

Another way is to use PHP's atomic library to implement thread-safe singleton mode through atomic operations. The specific code is as follows:

class Singleton
{
    private static $instance;

    private function __construct()
    {
        // 保证外部无法通过new关键字创建实例
    }

    public static function getInstance()
    {
        $closure = function () {
            self::$instance = new self();
        };

        $atomic = new SwooleAtomic();

        if (!isset(self::$instance)) {
            if ($atomic->cmpset(0, 1)) {
                $closure();
                $atomic->set(0);
            } else {
                while (!isset(self::$instance)) {
                    // 占位,避免空循环
                }
            }
        }
        return self::$instance;
    }
}

In the above code, we use PHP's swoole library and use atomic operations to achieve thread safety. Create an atomic variable through the Atomic class of swoole. When the atomic variable is 0, set the atomic variable to 1 through the cmpset method, and then create an instance; create After completing the instance, reset the atomic variable to 0. When other threads enter the code block, they will continue to wait in a loop until $instance is not empty.

It should be noted that not all PHP environments support the swoole library, so you need to confirm whether the PHP environment can support it before using it.

To sum up, when using the singleton mode in PHP, you need to consider thread safety issues. Locking or atomic operations can ensure that only one thread can create an instance, but this also reduces performance. Choose the appropriate method according to the actual situation to improve program performance while ensuring thread safety.

The above is the detailed content of Thoughts on thread safety issues in singleton mode in PHP. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn