多线程java程序交替打印偶数和奇数
在一次采访中,我被要求编写一个双线程Java程序。在这个程序中,一个线程应该打印偶数,另一个线程应该交替打印奇数 样本输出: 线程1:1 线程2:2 线程1:3 线程2:4 ... 等等 我写了下面的程序。一个类多线程java程序交替打印偶数和奇数,java,multithreading,synchronization,Java,Multithreading,Synchronization,在一次采访中,我被要求编写一个双线程Java程序。在这个程序中,一个线程应该打印偶数,另一个线程应该交替打印奇数 样本输出: 线程1:1 线程2:2 线程1:3 线程2:4 ... 等等 我写了下面的程序。一个类任务,它包含两种分别打印偶数和奇数的方法。在main方法中,我创建了两个线程来调用这两个方法。面试官要求我进一步改进,但我想不出有什么改进。有没有更好的方法来编写相同的程序 class Task { boolean flag; public Task(boolean f
任务
,它包含两种分别打印偶数和奇数的方法。在main方法中,我创建了两个线程来调用这两个方法。面试官要求我进一步改进,但我想不出有什么改进。有没有更好的方法来编写相同的程序
class Task
{
boolean flag;
public Task(boolean flag)
{
this.flag = flag;
}
public void printEven()
{
for( int i = 2; i <= 10; i+=2 )
{
synchronized (this)
{
try
{
while( !flag )
wait();
System.out.println(i);
flag = false;
notify();
}
catch (InterruptedException ex)
{
ex.printStackTrace();
}
}
}
}
public void printOdd()
{
for( int i = 1; i < 10; i+=2 )
{
synchronized (this)
{
try
{
while(flag )
wait();
System.out.println(i);
flag = true;
notify();
}
catch(InterruptedException ex)
{
ex.printStackTrace();
}
}
}
}
}
public class App {
public static void main(String [] args)
{
Task t = new Task(false);
Thread t1 = new Thread( new Runnable() {
public void run()
{
t.printOdd();
}
});
Thread t2 = new Thread( new Runnable() {
public void run()
{
t.printEven();
}
});
t1.start();
t2.start();
}
}
类任务
{
布尔标志;
公共任务(布尔标志)
{
this.flag=flag;
}
公共无效打印偶()
{
对于(int i=2;i嗯,有很多选择。我可能会使用SynchronousQueue
来代替(我不喜欢低级wait
/notify
并尝试使用高级并发原语)。此外,printOdd
和printEven
可以合并到单个方法中,不需要附加标志:
public class App {
static class OddEven implements Runnable {
private final SynchronousQueue<Integer> queue = new SynchronousQueue<>();
public void start() throws InterruptedException {
Thread oddThread = new Thread(this);
Thread evenThread = new Thread(this);
oddThread.start();
queue.put(1);
evenThread.start();
}
@Override
public void run() {
try {
while (true) {
int i = queue.take();
System.out.println(i + " (" + Thread.currentThread() + ")");
if (i == 10)
break;
queue.put(++i);
if (i == 10)
break;
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
public static void main(String[] args) throws InterruptedException {
new OddEven().start();
}
}
公共类应用程序{
静态类Odd偶数实现可运行{
private final SynchronousQueue=new SynchronousQueue();
public void start()引发InterruptedException{
螺纹oddThread=新螺纹(此);
线程evenThread=新线程(此线程);
oddThread.start();
队列。put(1);
evenThread.start();
}
@凌驾
公开募捐{
试一试{
while(true){
int i=queue.take();
System.out.println(i+“(“+Thread.currentThread()+”);
如果(i==10)
打破
queue.put(++i);
如果(i==10)
打破
}捕捉(中断异常e){
抛出新的运行时异常(e);
}
}
}
公共静态void main(字符串[]args)引发InterruptedException{
新的奇偶();
}
}
像这样的短版本怎么样:
public class OddEven implements Runnable {
private static volatile int n = 1;
public static void main(String [] args) {
new Thread(new OddEven()).start();
new Thread(new OddEven()).start();
}
@Override
public void run() {
synchronized (this.getClass()) {
try {
while (n < 10) {
this.getClass().notify();
this.getClass().wait();
System.out.println(Thread.currentThread().getName() + ": " + (n++));
this.getClass().notify();
}
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
}
}
public类Odd偶数实现可运行{
私有静态易失性int n=1;
公共静态void main(字符串[]args){
新线程(新的奇偶数()).start();
新线程(新的奇偶数()).start();
}
@凌驾
公开募捐{
已同步(this.getClass()){
试一试{
而(n<10){
this.getClass().notify();
this.getClass().wait();
System.out.println(Thread.currentThread().getName()+“:”+(n++);
this.getClass().notify();
}
}捕获(中断异常例外){
例如printStackTrace();
}
}
}
}
正确启动线程有一点技巧-因此需要额外的notify()
来启动整个过程(而不是让两个进程都等待,或者要求主线程调用notify)另外,为了处理线程启动的可能性,在第二个线程启动之前,它是否工作并调用notify:)我的初始答案不起作用。编辑:
package test;
public final class App {
private static volatile int counter = 1;
private static final Object lock = new Object();
public static void main(String... args) {
for (int t = 0; t < 2; ++t) {
final int oddOrEven = t;
new Thread(new Runnable() {
@Override public void run() {
while (counter < 100) {
synchronized (lock) {
if (counter % 2 == oddOrEven) {
System.out.println(counter++);
}
}
}
}
}).start();
}
}
}
封装测试;
公共期末课程应用程序{
专用静态易失性int计数器=1;
私有静态最终对象锁=新对象();
公共静态void main(字符串…参数){
对于(int t=0;t<2;++t){
最终int oddOrEven=t;
新线程(newrunnable()){
@重写公共无效运行(){
同时(计数器<100){
已同步(锁定){
if(计数器%2==oddOrEven){
System.out.println(计数器++);
}
}
}
}
}).start();
}
}
}
有没有更好的方法来编写相同的程序
class Task
{
boolean flag;
public Task(boolean flag)
{
this.flag = flag;
}
public void printEven()
{
for( int i = 2; i <= 10; i+=2 )
{
synchronized (this)
{
try
{
while( !flag )
wait();
System.out.println(i);
flag = false;
notify();
}
catch (InterruptedException ex)
{
ex.printStackTrace();
}
}
}
}
public void printOdd()
{
for( int i = 1; i < 10; i+=2 )
{
synchronized (this)
{
try
{
while(flag )
wait();
System.out.println(i);
flag = true;
notify();
}
catch(InterruptedException ex)
{
ex.printStackTrace();
}
}
}
}
}
public class App {
public static void main(String [] args)
{
Task t = new Task(false);
Thread t1 = new Thread( new Runnable() {
public void run()
{
t.printOdd();
}
});
Thread t2 = new Thread( new Runnable() {
public void run()
{
t.printEven();
}
});
t1.start();
t2.start();
}
}
好的,问题是,编写程序的唯一好方法是使用一个线程。如果你想让一个程序按这个顺序执行X,Y,Z,那么就编写一个执行X,Y,Z的过程。没有比这更好的方法了
以下是我在与面试官讨论了这些主题的恰当性之后所写的内容
import java.util.concurrent.SynchronousQueue;
import java.util.function.Consumer;
public class EvenOdd {
public static void main(String[] args) {
SynchronousQueue<Object> q1 = new SynchronousQueue<>();
SynchronousQueue<Object> q2 = new SynchronousQueue<>();
Consumer<Integer> consumer = (Integer count) -> System.out.println(count);
new Thread(new Counter(q1, q2, 2, 1, consumer)).start();
new Thread(new Counter(q2, q1, 2, 2, consumer)).start();
try {
q1.put(new Object());
} catch (InterruptedException ex) {
throw new RuntimeException(ex);
}
}
private static class Counter implements Runnable {
final SynchronousQueue<Object> qin;
final SynchronousQueue<Object> qout;
final int increment;
final Consumer<Integer> consumer;
int count;
Counter(SynchronousQueue<Object> qin, SynchronousQueue<Object> qout,
int increment, int initial_count,
Consumer<Integer> consumer) {
this.qin = qin;
this.qout = qout;
this.increment = increment;
this.count = initial_count;
this.consumer = consumer;
}
public void run() {
try {
while (true) {
Object token = qin.take();
consumer.accept(count);
qout.put(token);
count += increment;
}
} catch (InterruptedException ex) {
throw new RuntimeException(ex);
}
}
}
}
import java.util.concurrent.SynchronousQueue;
导入java.util.function.Consumer;
公共课偶数{
公共静态void main(字符串[]args){
SynchronousQueue q1=新的SynchronousQueue();
SynchronousQueue q2=新的SynchronousQueue();
消费者消费者=(整数计数)->System.out.println(计数);
新线程(新计数器(q1、q2、2、1、使用者)).start();
新线程(新计数器(q2、q1、2、2、使用者)).start();
试一试{
q1.放置(新对象());
}捕获(中断异常例外){
抛出新的运行时异常(ex);
}
}
私有静态类计数器实现可运行{
最终同步队列;
最终同步队列qout;
最终整数增量;
最终消费者;
整数计数;
计数器(SynchronousQueue qin、SynchronousQueue qout、,
整数增量,整数初始计数,
(消费者){
this.qin=qin;
this.qout=qout;
这个增量=增量;
this.count=初始计数;
这个。消费者=消费者;
}
公开募捐{
试一试{
while(true){
对象标记=qin.take();
消费者。接受(计数);
qout.put(令牌);
计数+=增量;
}
}抓住(我)