code: def test_multi_threading(
      self, ray_start_regular_shared, num_threads, monkeypatch
  ):
      monkeypatch.setattr(
          ray.data.datasource.image_datasource.ImageDatasource,
          "_NUM_THREADS_PER_TASK",
          num_threads,
      )
      ds = ray.data.read_images(
          "example://image-datasets/simple",
          parallelism=1,
          include_paths=True,
      )
      paths = [
          item["path"][-len("image1.jpg") :] for item in ds.take_all()
      ]
      if num_threads > 1:
          # If there are more than 1 threads, the order is not guaranteed.
          paths = sorted(paths)
      expected_paths = ["image1.jpg", "image2.jpg", "image3.jpg"]
      assert paths == expected_paths
  
imports: import os
  import tempfile
  from typing import Dict
  import numpy
  import pyarrow
  import pytest
  from fsspec.implementations.local import LocalFileSystem
  from PIL import Image
  import ray
  from ray.data.datasource import Partitioning
  from ray.data.datasource.file_meta_provider import FastFileMetadataProvider
  from ray.data.datasource.image_datasource import ImageDatasource, _ImageFileMetadataProvider
  from ray.data.extensions import ArrowTensorType
  from ray.data.tests.conftest import *
  from ray.data.tests.mock_http_server import *
  from ray.tests.conftest import *
label_desc: Use image node_id 2 for calling the TestReadImages obj's underlying member method code with example usage: obj.test_multi_threading(ray_start_regular_shared, num_threads, monkeypatch) without return types