我目前正在尝试编写一个解决此问题的Java程序。
“推广双线程Peterson锁的另一种方法是在二叉树中安排一些双线程的Peterson锁。假设n是2的幂。每个线程被分配一个叶锁,它与一个共享其他线程。每个锁将一个线程视为线程0,另一个线程视为线程1.“
我觉得我已经解决了,但我的输出并不总是正确的。我怀疑我的问题是在我的锁定方法的for循环中调用经过验证的Peterson锁(Peterson锁没有错误,因为它是为了解决这个问题而提供的)。我基本上构建了一个平衡的二叉树,声明了一个Peterson Algorithm实例的数组,并且,当每个线程进来时,我使用树作为索引并调用Peterson锁。
package mutex;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
public class tree_lock implements Lock{
int total_instances;
int thread_instances = 0;
int N;
static int cnt = 0;
static int cnt2 = 0;
int flag = 0;
Node root;
Peterson[] PeterInstances;
int[] IncomingThreadIDs;
final private ThreadLocal<Integer> THREAD_ID2 = new ThreadLocal<Integer>(){
final private AtomicInteger id2 = new AtomicInteger(0);
protected Integer initialValue(){
return id2.getAndIncrement();
}
};
//Constructor : tree_lock Constructor
//Input : n, the number of threads
//Descritpion : Determine number of instances fore each thread, Create IDs for each thread,
// Create Balanced Binary Tree of with keys numbered from 0 to n
tree_lock(int n)
{
N=n;
int temp = n;
total_instances = n - 1;
int[] IDs = new int[total_instances];
//Determine number of instances of each thread
while(temp != 1)
{
temp /=2;
thread_instances++;
}
PeterInstances = new Peterson[total_instances];
for(int i = 0; i < total_instances; i++)
{
PeterInstances[i] = new Peterson();
}
IncomingThreadIDs = new int[n];
//Create IDs for each thread
for(int i = 0; i < n;i+=2)
{
IncomingThreadIDs[i] = cnt;
IncomingThreadIDs[i+1] = cnt;
cnt+=2;
}
//Create array with keys for each node in binary tree
for(int i = 0; i < total_instances;i++)
{
IDs[i]=i;
}
//Create binary tree with keys from above array
BuildTree(0,IDs.length-1,IDs);
}
//Function : BuildTree
//Input : lowest index of array, high index of array, pointer to array
//Output : Balanced Binary Tree
//Description: Createds a Balanced Binary Tree
//Credit to: http://linwdav.blogspot.com/2011/06/how-to-build-balanced-binary-search.html
public Node BuildTree(int low, int high, int[] arr)
{
if(low > high)
return null;
else
{
int mid = (low + high)/2;
Node node = new Node(arr[mid]);
if(flag == 0)
{
root = node;
flag++;
}
node.leftChild = BuildTree(low,(mid-1),arr);
node.rightChild = BuildTree((mid+1),high,arr);
return node;
}
}
//Function : findNodeParent
//Input : key for a node
//Output : key of parent node
//Description : Determines the key for a parent node
public int findNodeParent(int key)
{
if(root.key == key)
return -1;
Node focusNode = root;
while(focusNode.leftChild.key != key && focusNode.rightChild.key != key)
{
if(key < focusNode.key)
{
focusNode = focusNode.leftChild;
}
else
{
focusNode = focusNode.rightChild;
}
}
return focusNode.key;
}
//Function : lock
//Description : locks other threads
public void lock()
{
//get thread ID
int cnt3 = (THREAD_ID2.get() % N);
int[] path = new int[thread_instances];
path[0] = IncomingThreadIDs[cnt3];
//create path to root node
for(int k = 1; k < thread_instances; k++)
{
path[k] = findNodeParent(path[k-1]);
}
//attempt to lock thread up to root node
for(int i = 0; i < thread_instances; i++)
{
//********************************
//Problem is here!!!!!!!!!!!!!!!
PeterInstances[path[i]].lock();
//ThreadID = findNodeParent(ThreadID);
}
}
//Function : unlock
//Description : unlocks other threads
public void unlock()
{
//get thread ID
int cnt3 = (THREAD_ID2.get() % N);
//create path to root node
int[] path = new int[thread_instances];
path[0] = IncomingThreadIDs[cnt3];
for(int k = 1; k < thread_instances; k++)
{
path[k] = findNodeParent(path[k-1]);
}
//attempt to unlock thread to the node
for(int i = thread_instances - 1; i >= 0; i--)
{
PeterInstances[path[i]].unlock();
}
}
// Any class implementing Lock must provide these methods
public Condition newCondition() {
throw new java.lang.UnsupportedOperationException();
}
public boolean tryLock(long time,
TimeUnit unit)
throws InterruptedException {
throw new java.lang.UnsupportedOperationException();
}
public boolean tryLock() {
throw new java.lang.UnsupportedOperationException();
}
public void lockInterruptibly() throws InterruptedException {
throw new java.lang.UnsupportedOperationException();
}
}
class Node
{
int key;
Node leftChild;
Node rightChild;
Node parent;
Node(int key)
{
this.key = key;
}
}
答案 0 :(得分:0)
你已经准确地指出了这个问题。您必须使此代码同步。我猜你正在调用的超类lock()是不同步的。
这样做可以解决问题。
synchronized (this){
PeterInstances[path[i]].lock();
}
希望它有所帮助。