在Java中使用偶数和奇数线程以自然顺序打印数字
我知道以前有人问过这个问题,但我不明白为什么我的解决方案对我不起作用。我有两个线程偶数和奇数,一个打印偶数,另一个打印奇数。当我启动线程时,我希望输出是自然的数字顺序,比如0 1 2 3..等等。这是我的代码:- [更新]在Java中使用偶数和奇数线程以自然顺序打印数字,java,multithreading,Java,Multithreading,我知道以前有人问过这个问题,但我不明白为什么我的解决方案对我不起作用。我有两个线程偶数和奇数,一个打印偶数,另一个打印奇数。当我启动线程时,我希望输出是自然的数字顺序,比如0 1 2 3..等等。这是我的代码:- [更新] public class ThreadCommunication { public static void main(String... args) throws InterruptedException { final ThreadCommunication o
public class ThreadCommunication {
public static void main(String... args) throws InterruptedException
{
final ThreadCommunication obj = new ThreadCommunication();
Thread even = new Thread(){
@Override
public void run()
{
for(int i=0;i<10;i=i+2){
synchronized(obj){
System.out.println(i);
try {
obj.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
};
Thread odd = new Thread(){
@Override
public void run()
{
for(int i=1;i<10;i=i+2){
synchronized(obj){
System.out.println(i);
obj.notify();
}
}
}
};
even.start();
odd.start();
}
我做错了什么?编辑:
volatile static boolean isAlreadyWaiting = false;
Thread even = new Thread() {
@Override
public void run() {
synchronized (obj) {
for (int i = 0; i < 10; i = i + 2) {
System.out.println(i);
try {
if (!isAlreadyWaiting) {
isAlreadyWaiting = true;
obj.wait();
}
obj.notify();
isAlreadyWaiting=false;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
};
Thread odd = new Thread() {
@Override
public void run() {
synchronized (obj) {
for (int i = 1; i < 10; i = i + 2) {
System.out.println(i);
try {
if(isAlreadyWaiting){
obj.notify();
isAlreadyWaiting = false;
}
if (!isAlreadyWaiting) {
isAlreadyWaiting = true;
obj.wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
};
及
有关所有权的更多信息
此方法(wait或notify)只应由
是此对象监视器的所有者。线程成为的所有者
对象的监视器有以下三种方式之一:
一次只有一个线程可以拥有对象的监视器。@Pragnani Kinnera对您看到的异常是正确的。但是如果您想在
偶数
和奇数
之间切换,则需要将第二个同步块移动到循环中。否则,通知线程将以独占方式保持锁,直到循环完成。(与第一个线程相反,第一个线程在每一轮上都会产生锁。)
Thread奇数=新线程(){
@凌驾
公开募捐
{
对于(int i=1;i,以下是您的解决方案:
public class ThreadCommunication {
public static void main(String args[]) throws InterruptedException
{
final ThreadCommunication obj = new ThreadCommunication();
Thread even = new Thread("Even Thread"){
@Override
public void run()
{
for(int i=0;i<10;i=i+2){
System.out.println(i);
synchronized(obj){
obj.notify();
}
synchronized(obj){
try {
obj.wait();
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
};
Thread odd = new Thread(){
@Override
public void run()
{
for(int i=1;i<10;i=i+2){
try {
synchronized(obj){
obj.wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(i);
synchronized(obj){
obj.notifyAll();
}
}
}
};
even.start();
odd.start();
}
}
公共类线程通信{
公共静态void main(字符串args[])引发InterruptedException
{
最终线程通信obj=新线程通信();
线程偶数=新线程(“偶数线程”){
@凌驾
公开募捐
{
对于(int i=0;i)您的回答帮助我消除了异常,但我仍然无法获得预期的正确输出。我已更新了代码。@Surajhk您应该放置try{obj.wait();}catch(InterruptedException e){e.printStackTrace();}
此代码位于for循环之外,因为您的上一个代码将打印一个偶数,然后偶数线程将等待我期望的输出0123456789@PragnaniKinnera,如果第二个线程首先获得锁,则此代码将死锁。它也不考虑虚假唤醒。将1023456789
作为输出,您将应该强制偶数
线程在奇数
线程之前启动。问题只与每个线程打印的第一个数字有关,它们从2
开始工作正常。编辑:在尝试{}catch{}之后移动println
应该足够了。我仍然无法获得一致的预期输出。我已更新了question@Surajhk您的预期输出是什么?123456789
?我的预期输出是0123456789
obj.wait();
obj.notify();
Thread odd = new Thread(){
@Override
public void run()
{
for(int i=1;i<10;i=i+2){
synchronized(obj){
System.out.println(i);
notify();
}
}
}
};
public class ThreadCommunication {
public static void main(String args[]) throws InterruptedException
{
final ThreadCommunication obj = new ThreadCommunication();
Thread even = new Thread("Even Thread"){
@Override
public void run()
{
for(int i=0;i<10;i=i+2){
System.out.println(i);
synchronized(obj){
obj.notify();
}
synchronized(obj){
try {
obj.wait();
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
};
Thread odd = new Thread(){
@Override
public void run()
{
for(int i=1;i<10;i=i+2){
try {
synchronized(obj){
obj.wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(i);
synchronized(obj){
obj.notifyAll();
}
}
}
};
even.start();
odd.start();
}
}