func (pq *PriorityQueue) Put(items ...Item) error {
	if len(items) == 0 {
		return nil
	}
	pq.lock.Lock()
	if pq.disposed {
		pq.lock.Unlock()
		return disposedError
	}
	for _, item := range items {
		pq.items.insert(item)
	}
	for {
		sema := pq.waiters.get()
		if sema == nil {
			break
		}
		sema.response.Add(1)
		sema.wg.Done()
		sema.response.Wait()
		if len(pq.items) == 0 {
			break
		}
	}
	pq.lock.Unlock()
	return nil
}
Put adds items to the queue.
package queue
import (
	"sort"
	"sync"
)
type Item interface {
	Compare(other Item) int
}
type priorityItems []Item
func (items *priorityItems) get(number int) []Item {
	returnItems := make([]Item, 0, number)
	index := 0
	for i := 0; i < number; i++ {
		if i >= len(*items) {
			break
		}
		returnItems = append(returnItems, (*items)[i])
		(*items)[i] = nil
		index++
	}
	*items = (*items)[index:]
	return returnItems
}
func (items *priorityItems) insert(item Item) {
	if len(*items) == 0 {
		*items = append(*items, item)
		return
	}
	equalFound := false
	i := sort.Search(len(*items), func(i int) bool {
		result := (*items)[i].Compare(item)
		if result == 0 {
			equalFound = true
		}
		return result >= 0
	})
	if equalFound {
		return
	}
	if i == len(*items) {
		*items = append(*items, item)
		return
	}
	*items = append(*items, nil)
	copy((*items)[i+1:], (*items)[i:])
	(*items)[i] = item
}
type PriorityQueue struct {
	waiters     waiters
	items       priorityItems
	lock        sync.Mutex
	disposeLock sync.Mutex
	disposed    bool
}