我想要一种在单独的线程中打印奇数和偶数的算法。输出应该是顺序1,2,3.4 ,.....
这里可以使用Executor框架。我见过related question on SO但是在C中。我想在这里实现Java。
答案 0 :(得分: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
答案 1 :(得分: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);
}
}
答案 2 :(得分: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");
}
答案 3 :(得分: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!");
}
}
答案 4 :(得分: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();
}
}
}
答案 5 :(得分: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));
}
}
答案 6 :(得分: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");
}
}