Implement a thread-safe bounded priority queue for tasks. The queue stores tasks as (priority, task_id, payload) and supports concurrent producers and consumers. Write a class with methods push(priority, task_id, payload), pop(), and size(). If the queue is full, push must block until space is available; if it is empty, pop must block until an item is available. Higher priority values must be returned first, and tasks with the same priority must be returned in FIFO insertion order.
def run_priority_queue_demo(capacity, operations):