Two locks are used, putlock and takelock
In this way, it is actually equivalent to two threads
However, there will also be concurrency problems when two threads operate on pointers.
If the number of queue elements is greater than 1, there will be no problem, because put is at the end of the queue, and take is at the head of the queue
If the number of queue elements is 0 or 1, it is possible
In terms of design, put first, then add 1 to cas. The thread to be fetched is obtained in the for loop. First, check whether the fetched cas is greater than 0, so there is a sequence: it must be finished before it can be fetched, not one side. Put aside and fetch, so here access and access are mutually exclusive.