Java 使用2个线程打印偶数和奇数
您好,我正在尝试使用两个线程(名为EvenThread和OddThread)打印偶数和奇数,有时我得到了正确的结果,有时没有,请任何人帮助我Java 使用2个线程打印偶数和奇数,java,multithreading,Java,Multithreading,您好,我正在尝试使用两个线程(名为EvenThread和OddThread)打印偶数和奇数,有时我得到了正确的结果,有时没有,请任何人帮助我 package com.java8; public class EvenOddExample { public static synchronized void print(int i,String name){ System.out.println(i+"--->"+name); } public
package com.java8;
public class EvenOddExample {
public static synchronized void print(int i,String name){
System.out.println(i+"--->"+name);
}
public static void main(String[] args) throws InterruptedException {
EvenThread e= new EvenThread();
e.start();
OddThread o=new OddThread();
o.start();
}
public static class EvenThread extends Thread{
public void run() {
for(int i=0;i<10;i++){
if(i%2==0){
print(i,"Even");
}else{
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
public static class OddThread extends Thread{
@Override
public void run() {
for(int i=1;i<10;i++){
if(i%2!=0){
print(i,"Odd");
}else{
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
}
package com.java8;
公共类的例子{
公共静态同步无效打印(int i,字符串名称){
System.out.println(i+“-->”+名称);
}
公共静态void main(字符串[]args)引发InterruptedException{
EvenThread e=新的EvenThread();
e、 start();
OddThread o=新的OddThread();
o、 start();
}
公共静态类EvenThread扩展线程{
公开募捐{
对于(int i=0;i您需要在两个线程之间发送一些信号。将synchronized
放在print
方法上可以简单地保证一次只能有一个线程进入该方法。要将线程按顺序放入Object.wait()
和Object.notify{All}()
方法,可以使用
实际上,这是某种发送方-接收方同步问题。根据所述问题的示例(请阅读本页以了解此同步的工作原理),我修改了您的代码。此外,我使用了ExecutorService
和Callable
,而不是扩展线程
,:
import java.util.concurrent.Callable;
导入java.util.concurrent.ExecutorService;
导入java.util.concurrent.Executors;
公共类的例子{
私有静态布尔值evensTurn=true;
私有静态对象监视器=新对象();
公共静态无效打印(int i,字符串名称){
System.out.println(i+“-->”+名称);
}
公共静态void main(字符串[]args)引发InterruptedException{
final ExecutorService ExecutorService=Executors.newFixedThreadPool(2);
executorService.submit(new EvenCallable());
executorService.submit(新的OddCallable());
executorService.shutdown();
}
公共静态类EvenCallable实现了Callable{
@凌驾
public Void call()引发InterruptedException{
对于(int i=0;i<10;i++){
如果(i%2==0){
同步(监视器){
而(!evensTurn){//不轮到你了?
monitor.wait();//在循环中等待monitor处理虚假唤醒
}
打印(i,“偶数”);
evensTurn=false;//需要运行下一个奇数
monitor.notifyAll();//唤醒奇数线程
}
}否则{
睡眠(1000);
}
}
返回null;
}
}
公共静态类OddCallable实现了Callable{
@凌驾
public Void call()引发InterruptedException{
对于(int i=1;i<10;i++){
如果(i%2!=0){
同步(监视器){
while(evensTurn){
monitor.wait();
}
印刷品(i,“奇数”);
evensTurn=true;
monitor.notifyAll();
}
}否则{
睡眠(1000);
}
}
返回null;
}
}
}
synchronized用于锁定另一个线程的访问,当锁定的对象空闲时,它不保证下一个被称为线程。您可以使用信号量进行线程间通信:
private static Semaphore[] semaphores = {new Semaphore(0), new Semaphore(1)};
static void print(int i, String name) {
try {
semaphores[(i + 1) % 2].acquire();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
System.out.println(i + "--->" + name);
semaphores[i % 2].release();
}
公共类打印机{
静态布尔标志=true;
公共静态void main(字符串[]args){
类奇数实现可运行{
@凌驾
公开募捐{
对于(int i=1;i“correct result”是什么意思?让eventhread从2开始,oddThread从1开始,循环(打印->将2添加到值)更改但同样发生1->奇数2->偶数3->奇数4->偶数6->偶数5->奇数8->偶数7->奇数9->奇数你的意思是有时print
在一行中打印几个奇数,例如?因为你将synchronized
放在静态方法上,所以当调用print
。这并不意味着一个线程不能连续多次调用print
。是的@michalk确切地说,问题是是是的,这样做可能会跳过一半的数字这绝对是错误的!!!你的睡眠在哪里()?你可以尝试添加睡眠()在不同的延迟情况下,您会看到它有时会卡住,无法打印到10
private static Semaphore[] semaphores = {new Semaphore(0), new Semaphore(1)};
static void print(int i, String name) {
try {
semaphores[(i + 1) % 2].acquire();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
System.out.println(i + "--->" + name);
semaphores[i % 2].release();
}
public class EvenOddPrinter {
static boolean flag = true;
public static void main(String[] args) {
class Odd implements Runnable {
@Override
public void run() {
for (int i = 1; i <= 10;) {
if (EvenOddPrinter.flag) {
System.out.println(i + "--->odd");
i += 2;
EvenOddPrinter.flag = !EvenOddPrinter.flag;
}
}
}
}
class Even implements Runnable {
@Override
public void run() {
for (int i = 2; i <= 10;) {
if (!EvenOddPrinter.flag) {
System.out.println(i + "---->even");
i += 2;
EvenOddPrinter.flag = !EvenOddPrinter.flag;
}
}
}
}
Runnable odd = new Even();
Runnable even = new Odd();
Thread t1 = new Thread(odd, "Odd");
Thread t2 = new Thread(even, "Even");
t1.start();
t2.start();
}
}