假设我有10个线程将变量加1。假设线程1首先增加变量,然后线程2和线程3依次增加。在所有10个线程都增加了变量之后。我需要以某种方式减少相同的变量。
递减,如果Thread-1首先使变量递增,那么它最后应递减。
我们需要在不设置线程优先级的情况下执行此操作。
答案 0 :(得分:1)
这似乎有效。本质上,我创建了10
线程,并使用enum
专门标识了其中之一。他们都尝试增加共享整数,以标识自己。增量器通过注意到过渡到1
来检测第一个增量,如果它是Special
线程,则返回true
。
还有一个CountDownLatch
用于同步所有线程,以确保至少有两种选择的机会。我从8600
首先到达那里的10000
测试中获得了Special
。该值将取决于许多变量。
enum Who {
Special, Normal;
}
class PriorityIncrementer {
final AtomicInteger i = new AtomicInteger(0);
boolean inc(Who who) {
return i.incrementAndGet() == 1 && who == Who.Special;
}
public void dec() {
i.decrementAndGet();
}
}
class TestRunnable implements Runnable {
final Who me;
final PriorityIncrementer incrementer;
final CountDownLatch latch;
public TestRunnable(PriorityIncrementer incrementer, CountDownLatch latch, Who me) {
this.incrementer = incrementer;
this.latch = latch;
this.me = me;
}
@Override
public void run() {
// Wait for all others to get here.
latch.countDown();
try {
// Wait here until everyone os waiting here.
latch.await();
// Do it.
if(incrementer.inc(me)) {
// I was first and special, decrement after.
incrementer.dec();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private boolean test(int count) throws InterruptedException {
Thread[] threads = new Thread[count];
// The shared incrementer.
PriorityIncrementer incrementer = new PriorityIncrementer();
// Arrange for all of them to synchronise.
CountDownLatch latch = new CountDownLatch(threads.length+1);
// One special.
threads[0] = new Thread(new TestRunnable(incrementer, latch, Who.Special));
// The rest are normal.
for(int i = 1; i < threads.length; i++) {
threads[i] = new Thread(new TestRunnable(incrementer, latch, Who.Normal));
}
// Start them up.
for (Thread thread : threads) {
thread.start();
}
// Wait a moment.
Thread.sleep(1);
// Start them all going.
latch.countDown();
// Wait for them to finish.
for (Thread thread : threads) {
thread.join();
}
// Who won?
return incrementer.i.get() < count;
}
public void test() throws InterruptedException {
final int tests = 10000;
int specialWasFirstCount = 0;
for (int i = 0; i < tests; i++) {
if(test(10)) {
specialWasFirstCount += 1;
}
}
System.out.println("Specials: "+specialWasFirstCount+"/"+tests);
}
答案 1 :(得分:1)
您可以使用很多方法,例如:
public class Main {
public static void main(String[] args) throws Exception {
for(int i=0;i<10;i++){
final int _i=i;
Thread t = new Thread(new T(_i));
t.start();
}
}
public static class T implements Runnable{
int threadNumber;
public T(int threadNumber) {
this.threadNumber=threadNumber;
}
@Override
public void run() {
increase(this);
}
}
static Thread[] threads = new Thread[10];
static int number =0;
static Object generalLock=new Object();
public static void increase(T t){
int myNumber=0;
synchronized (generalLock){
myNumber=number;
System.out.println("i am "+number+" incrementing, my real number "+t.threadNumber);
threads[number]=Thread.currentThread();
number++;
}
while (threads[9]==null){
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
for(int i=9;i>myNumber;i--){
try {
threads[i].join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
synchronized (generalLock){
System.out.println("i am "+number+" decrementing, my real number "+t.threadNumber);
number--;
}
}
}
输出示例:
i am 0 incrementing, my real number 1
i am 1 incrementing, my real number 8
i am 2 incrementing, my real number 9
i am 3 incrementing, my real number 7
i am 4 incrementing, my real number 6
i am 5 incrementing, my real number 5
i am 6 incrementing, my real number 0
i am 7 incrementing, my real number 4
i am 8 incrementing, my real number 3
i am 9 incrementing, my real number 2
i am 9 decrementing, my real number 2
i am 8 decrementing, my real number 3
i am 7 decrementing, my real number 4
i am 6 decrementing, my real number 0
i am 5 decrementing, my real number 5
i am 4 decrementing, my real number 6
i am 3 decrementing, my real number 7
i am 2 decrementing, my real number 9
i am 1 decrementing, my real number 8
i am 0 decrementing, my real number 1
注意:您可以使用简单的Runnable,我创建T类来显示线程号,以便在递增/递减时打印它