मैं Ceki द्वारा इस लेख पढ़ सकते हैं और कैसे पक्षपातपूर्ण सेमाफोर अधिग्रहण हो सकता है रुचि थी (के बाद से मुझे लगा कि "पक्षपातपूर्ण ताला" व्यवहार के रूप में अच्छी तरह से सेमाफोर में मतलब होता है ..)। मेरे प्रोसेसर और एक सन जेवीएम 1.6 के साथ मेरे हार्डवेयर पर, यह वास्तव में बहुत समान पट्टा में परिणाम देता है।
वैसे भी, मैंने अपने दूसरे उत्तर में लिखी गई रणनीति के साथ सेमफोर के पट्टे पर "पूर्वाग्रह" करने की भी कोशिश की। एकमात्र अतिरिक्त yield
कथन अकेले महत्वपूर्ण पूर्वाग्रह में परिणाम देता है। आपकी समस्या अधिक जटिल है, लेकिन शायद आप अपने विचार के साथ इसी तरह के परीक्षण करते हैं और आपको क्या मिलेगा देख सकते हैं :)
नोट कोड नीचे Ceki के कोड पर आधारित है here
कोड:
import java.util.concurrent.*;
public class BiasedSemaphore implements Runnable {
static ThreadLocal<Boolean> favored = new ThreadLocal<Boolean>(){
private boolean gaveOut = false;
public synchronized Boolean initialValue(){
if(!gaveOut){
System.out.println("Favored " + Thread.currentThread().getName());
gaveOut = true;
return true;
}
return false;
}
};
static int THREAD_COUNT = Runtime.getRuntime().availableProcessors();
static Semaphore SEM = new Semaphore(1);
static Runnable[] RUNNABLE_ARRAY = new Runnable[THREAD_COUNT];
static Thread[] THREAD_ARRAY = new Thread[THREAD_COUNT];
private int counter = 0;
public static void main(String args[]) throws InterruptedException {
printEnvironmentInfo();
execute();
printResults();
}
public static void printEnvironmentInfo() {
System.out.println("java.runtime.version = "
+ System.getProperty("java.runtime.version"));
System.out.println("java.vendor = "
+ System.getProperty("java.vendor"));
System.out.println("java.version = "
+ System.getProperty("java.version"));
System.out.println("os.name = "
+ System.getProperty("os.name"));
System.out.println("os.version = "
+ System.getProperty("os.version"));
}
public static void execute() throws InterruptedException {
for (int i = 0; i < THREAD_COUNT; i++) {
RUNNABLE_ARRAY[i] = new BiasedSemaphore();
THREAD_ARRAY[i] = new Thread(RUNNABLE_ARRAY[i]);
System.out.println("Runnable at "+i + " operated with "+THREAD_ARRAY[i]);
}
for (Thread t : THREAD_ARRAY) {
t.start();
}
// let the threads run for a while
Thread.sleep(10000);
for (int i = 0; i< THREAD_COUNT; i++) {
THREAD_ARRAY[i].interrupt();
}
for (Thread t : THREAD_ARRAY) {
t.join();
}
}
public static void printResults() {
System.out.println("Ran with " + THREAD_COUNT + " threads");
for (int i = 0; i < RUNNABLE_ARRAY.length; i++) {
System.out.println("runnable[" + i + "]: " + RUNNABLE_ARRAY[i]);
}
}
public void run() {
while (!Thread.currentThread().isInterrupted()) {
if (favored.get()) {
stuff();
} else {
Thread.yield();
// try {
// Thread.sleep(1);
// } catch (InterruptedException e) {
// Thread.currentThread().interrupt();
// }
stuff();
}
}
}
private void stuff() {
if (SEM.tryAcquire()) {
//favored.set(true);
counter++;
try {
Thread.sleep(10);
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
}
SEM.release();
} else {
//favored.set(false);
}
}
public String toString() {
return "counter=" + counter;
}
}
परिणाम:
java.runtime.version = 1.6.0_21-b07
java.vendor = Sun Microsystems Inc.
java.version = 1.6.0_21
os.name = Windows Vista
os.version = 6.0
Runnable at 0 operated with Thread[Thread-0,5,main]
Runnable at 1 operated with Thread[Thread-1,5,main]
Favored Thread-0
Ran with 2 threads
runnable[0]: counter=503
runnable[1]: counter=425
10 के बजाय 30 सेकंड के साथ की कोशिश की:
java.runtime.version = 1.6.0_21-b07
java.vendor = Sun Microsystems Inc.
java.version = 1.6.0_21
os.name = Windows Vista
os.version = 6.0
Runnable at 0 operated with Thread[Thread-0,5,main]
Runnable at 1 operated with Thread[Thread-1,5,main]
Favored Thread-1
Ran with 2 threads
runnable[0]: counter=1274
runnable[1]: counter=1496
पी.एस .: की तरह एक बहुत बुरा विचार "बाहर लटक" था लग रहा है। जब मैंने गैर-पसंदीदा धागे के लिए SEM.tryAcquire(1,TimeUnit.MILLISECONDS);
और SEM.tryAcquire()
को गैर-पसंदीदा धागे के लिए कॉल करने का प्रयास किया, तो गैर-पसंदीदा धागे को पसंदीदा धागे से लगभग 5 गुना अधिक परमिट मिला!
इसके अलावा, मैं यह भी जोड़ना चाहता हूं कि ये परिणाम केवल 1 विशेष स्थिति के तहत मापा जाता है, इसलिए यह स्पष्ट नहीं है कि ये उपाय अन्य स्थितियों में कैसे व्यवहार करते हैं।
यह सबसे अच्छा एक समवर्ती प्राथमिकता कतार की तरह कुछ के साथ हल नहीं किया जा सकते हैं? –
यह स्पष्ट नहीं है कि 'tryquor() '" प्रतीक्षा थ्रेड "से संबंधित है क्योंकि यह गैर-अवरुद्ध है। – axtavt
@Andrew हाँ शायद, मुझे नहीं पता कि उन कार्यों में से एक कैसे। – jjujuma