我想要一个在单独的线程中打印奇数和偶数的算法。输出应该是顺序的1,2,3.4 ,.....
Executor 框架可以在这里使用。我在 SO 上看到了一个相关的问题,但那是在 C 中。我想要一个 Java 实现在这里。
问问题
6401 次
7 回答
2
它是 jasons 的修改版本:
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;
public class Test {
public static void main(String[] args){
final int max = 100;
final AtomicInteger i = new AtomicInteger(0);
Executor dd = Executors.newFixedThreadPool(2);
final Object lock = new Object();
dd.execute(new Runnable() {
@Override
public void run() {
while (i.get() < max) {
if (i.get() % 2 == 0) {
System.out.print(" " + i.getAndAdd(1));
synchronized(lock){
lock.notify();
}
}else{
synchronized(lock){
try {
lock.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
});
dd.execute(new Runnable() {
@Override
public void run() {
while (i.get() < max) {
if (i.get() % 2 != 0) {
System.out.print(" " + i.getAndAdd(1));
synchronized(lock){
lock.notify();
}
}else{
synchronized(lock){
try {
lock.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
});
do {
try {
Thread.currentThread().sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
} while (i.get() != max);
System.out.println("\nDone");
}
}
免责声明:它不是最好的解决方案,当然也不是最快的,但它会产生正确的输出。
这就是输出:
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
Done
于 2012-07-10T11:28:06.813 回答
1
您的问题有点令人困惑,因为看起来您希望按顺序输出。
在这种情况下使用线程是没有意义的,因为它们会不断地相互协调以确定轮到谁输出它们的当前数字。
如果您不关心排序(例如,您可能会得到 1、2、3、5、4、6、8.7...),那么它可能是有意义的。
public class Test
{
private static final int NOT_APPLICABLE = 1;
private final ExecutorService executor;
public Test()
{
BlockingQueue<Runnable> queue = new ArrayBlockingQueue<Runnable>(2);
executor = new ThreadPoolExecutor(2, 2, NOT_APPLICABLE, TimeUnit.SECONDS, queue);
}
public void submitTask(Runnable task)
{
executor.submit(task);
}
private static class Counter implements Runnable
{
private int counter;
public Counter(int start)
{
this.counter = start;
}
@Override
public void run()
{
while (true)
{
System.out.println(counter);
counter += 2;
}
}
}
public static void main(String[] args)
{
Runnable odd = new Counter(1);
Runnable even = new Counter(2);
Test app = new Test();
app.submitTask(odd);
app.submitTask(even);
}
}
于 2012-07-10T11:21:16.770 回答
0
public static void main(String[] args) {
final int max = 100;
final AtomicInteger i = new AtomicInteger(0);
new Thread(new Runnable() {
@Override
public void run() {
while (i.get() < max) {
if (i.get() % 2 != 0) {
synchronized (i) {
System.out.print(" " + i.getAndAdd(1));
}
}
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
while (i.get() < max) {
if (i.get() % 2 == 0) {
synchronized (i) {
System.out.print(" " + i.getAndAdd(1));
}
}
}
}
}).start();
do {
try {
Thread.currentThread().sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
} while (i.get() != max);
System.out.println("\nDone");
}
于 2012-07-10T11:17:24.760 回答
0
一些忙等待的代码,最简单的。
package t1;
import java.util.concurrent.atomic.AtomicInteger;
public class Redx implements Runnable{
private final static int MAX = 99;
final AtomicInteger next;
final int odd;
public Redx(AtomicInteger next, int odd) {
super();
this.next = next;
this.odd = odd;
}
public void run(){
for(;;){
int n = next.get();
if (n > MAX)
break;
if ((n&1)==odd)
continue;
System.out.print(n+", ");
if ((n & 0x1F)==0x1F)//new line can be skipped
System.out.println();
next.lazySet(n+1);
}
}
public static void main(String[] args) {
final AtomicInteger next = new AtomicInteger(0);
Redx x0 = new Redx(next, 0);
Redx x1 = new Redx(next, 1);
new Thread(x0).start();
new Thread(x1).start();
for(;next.get()<=MAX;)
Thread.yield();
System.out.println();
System.out.println("Done!");
}
}
于 2012-07-10T15:43:57.127 回答
0
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class GenerateEvenOddNumberTest {
public static void main(String[] args) {
GenerateNumber GenNum = new GenerateNumber();
ExecutorService es = Executors.newFixedThreadPool(2);
es.execute(GenNum);
es.execute(GenNum);
}
}
class GenerateNumber implements Runnable{
private static final AtomicInteger nextId = new AtomicInteger(0);
// Thread local variable containing each thread's ID
private static final ThreadLocal<Integer> count =
new ThreadLocal<Integer>() {
@Override protected Integer initialValue() {
return nextId.getAndIncrement();
}
};
private static final AtomicBoolean bool = new AtomicBoolean(true);
// Thread local variable containing each thread's ID
private static final ThreadLocal<Boolean> even =
new ThreadLocal<Boolean>() {
@Override protected Boolean initialValue() {
return bool.getAndSet(false) ;
}
};
boolean isOdd = false;
Lock lock = new ReentrantLock();
Condition checkOdd = lock.newCondition();
Condition checkEven = lock.newCondition();
public void printEvenNumber(){
lock.lock();
try {
while(count.get()<500){
while(isOdd){
try {
checkEven.await();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("Thread Name "+Thread.currentThread().getName()+" "+count.get());
count.set(count.get()+2);
isOdd = true;
checkOdd.signal();
}
} finally {
lock.unlock();
}
}
public void printOddNumber(){
lock.lock();
try {
while(count.get()<500){
while(!isOdd){
try {
checkOdd.await();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("Thread Name "+Thread.currentThread().getName()+" "+count.get());
count.set(count.get()+2);
isOdd = false;
checkEven.signal();
}
} finally {
lock.unlock();
}
}
@Override
public void run() {
if(even.get()){
printEvenNumber();
}
else{
printOddNumber();
}
}
}
于 2013-08-29T13:05:18.923 回答
0
/* 使用 Semaphore 是打印奇偶数列的最简单方法 */
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
class Even implements Runnable {
private Semaphore s1;
private Semaphore s2;
private static volatile int num = 0;
Even(Semaphore s1, Semaphore s2) {
this.s1 = s1;
this.s2 = s2;
}
@Override
public void run() {
synchronized (s2) {
while (num < 99) {
try {
s1.acquire();
System.out.print(" " + num);
num += 2;
s2.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
class Odd implements Runnable {
private Semaphore s1;
private Semaphore s2;
private static volatile int num = 1;
Odd(Semaphore s1, Semaphore s2) {
this.s1 = s1;
this.s2 = s2;
}
@Override
public void run() {
synchronized (s1) {
while (num < 100) {
try {
s2.acquire();
System.out.print(" " + num);
num += 2;
s1.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
public class ExecOddEvenPrint {
public static void main(String[] args) {
ExecutorService exec = Executors.newFixedThreadPool(2);
Semaphore s1 = new Semaphore(1);
Semaphore s2 = new Semaphore(0);
exec.execute(new Even(s1, s2));
exec.execute(new Odd(s1, s2));
}
}
于 2016-09-14T07:02:52.593 回答
0
This will do:
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;
public class Threads implements Runnable{
static AtomicInteger x=new AtomicInteger(1);
public void generate()
{
//System.out.println("In generate");
synchronized(x){
if(x.get()%2==0)
System.out.println(x+" is EVEN");
else
System.out.println(x+" is ODD");
x.incrementAndGet();
}
}
@Override
public synchronized void run() {
//System.out.println("In run");
generate();
}
public static void main(String[] args) {
//System.out.println("In generateThreads");
ExecutorService pool=Executors.newFixedThreadPool(10);
for(int i=0;i<2;i++) // two threads
pool.submit(new Threads());
pool.shutdown();
while (!pool.isTerminated()) {
}
// System.out.println("DONEs");
}
}
于 2019-01-11T18:51:24.540 回答