写两个线程,其中一个打印1-52,一个打印A-Z,打印顺序是12A34B...5152Z。

anlian523 2017-06-20 04:49:21
执行结果为
12A56C910E1314G1718I2122K2526M2930O3334Q3738S4142U4546W4950Y
不知道为什么,不管是数字还是字母,都少13次,就是打印了一次,就会跳过一次,是因为我程序哪儿写错了吧

代码如下:

package testone;


public class print {

private boolean flag=true;//为真打印数字,为假打印字母

public print() {

}

public synchronized void printNumber(String s)
{
try
{
if(!flag)
{
wait();
}
else//为真时进入
{
System.out.print(s);
flag=false;
notifyAll();
}
}
catch(InterruptedException ex)
{
ex.printStackTrace();
}
}

public synchronized void printLetter(String s)
{
try
{
if(flag)
{
wait();
}
else//为假时进入
{
System.out.print(s);
flag=true;
notifyAll();
}
}
catch(InterruptedException ex)
{
ex.printStackTrace();
}
}

}



package testone;

public class numthread extends Thread{

public print printer;
public numthread(String name,print printer) {
super(name);
this.printer=printer;
// TODO Auto-generated constructor stub
}

public void run()
{
for(int i=1;i<=51;i+=2)
{
String s=i+""+(i+1);
printer.printNumber(s);
}
}
}


package testone;

public class letterthread extends Thread {

public print printer;
public letterthread(String name,print printer) {
super(name);
this.printer=printer;
// TODO Auto-generated constructor stub
}

public void run()
{
for(int i=1;i<=26;i+=1)
{
int temp=i+64;
char c=(char) temp;
printer.printLetter(c+"");
}
}

}


package testone;

public class printTest {

public static void main(String[] args) {
// TODO Auto-generated method stub

print printer=new print();
new numthread("打印数字线程",printer).start();;
new letterthread("打印字母线程",printer).start();

}

}

...全文
477 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
anlian523 2017-06-21
  • 打赏
  • 举报
回复
引用 4 楼 Jerrcy_Fly 的回复:
测试查看了一下,觉得原因是在于线程中的else{},修改之后的如下:
package test;
 
 
public class print {
 
    private  boolean flag=true;//为真打印数字,为假打印字母
     
    public print() {
         
    }
 
    public synchronized void printNumber(String s)
    {
        try
        {
            if(!flag)
            {
                wait();
            }
            System.out.print(s);
            flag=false;
            notifyAll();
        }
        catch(InterruptedException ex)
        {
            ex.printStackTrace();
        }
    }
     
    public synchronized void printLetter(String s)
    {
        try
        {
            if(flag)
            {
                wait();
            }
            System.out.print(s);
            flag=true;
            notifyAll();
        }
        catch(InterruptedException ex)
        {
            ex.printStackTrace();
        }
    }
 
}
把线程中的else去掉,再测试就可以了。
谢谢,经过测试,结果对了。但是可否讲一下加了else为什么就是不对,我有点当局者迷了。。。感觉有点想不透了。。。
anlian523 2017-06-21
  • 打赏
  • 举报
回复
引用 3 楼 scping880919 的回复:
很简单嘛。 if(flag) { wait(); } 在这里wait了,另一个线程唤醒它后,它就跳过了这一次打印继续执行。改为 if (flag) { wait(); System.out.print(s); } else// 为假时进入
两个方法都在那个位置都加了System.out.print(s);以后,结果是 1 2 A 3 4 5 6 B C 7 8 9 10 D E 11 12 13 14 F G 15 16 17 18 H I 19 20 21 22 J K 23 24 25 26 L 27 28 29 30 M N 31 32 33 34 O P 35 36 37 38 Q R 39 40 41 42 S T 43 44 45 46 U V 47 48 49 50 W 51 52 ,感觉还是不对。 就是每次循环都保证输出了,但是顺序并没有保证到。
nikyotensai 2017-06-21
  • 打赏
  • 举报
回复
 public synchronized void printNumber(String s)
    {
        try
        {
            if(!flag)
            {
                wait();
            }
            else//为真时进入
            {
                System.out.print(s);
                flag=false;
                notifyAll();
            }
        }
        catch(InterruptedException ex)
        {
            ex.printStackTrace();
        }
    }
就拿这段来说,比如传3的时候wait(),你觉得线程唤醒之后走什么?不可能去走else的
Jcon_ 2017-06-21
  • 打赏
  • 举报
回复
测试查看了一下,觉得原因是在于线程中的else{},修改之后的如下:
package test;
 
 
public class print {
 
    private  boolean flag=true;//为真打印数字,为假打印字母
     
    public print() {
         
    }
 
    public synchronized void printNumber(String s)
    {
        try
        {
            if(!flag)
            {
                wait();
            }
            System.out.print(s);
            flag=false;
            notifyAll();
        }
        catch(InterruptedException ex)
        {
            ex.printStackTrace();
        }
    }
     
    public synchronized void printLetter(String s)
    {
        try
        {
            if(flag)
            {
                wait();
            }
            System.out.print(s);
            flag=true;
            notifyAll();
        }
        catch(InterruptedException ex)
        {
            ex.printStackTrace();
        }
    }
 
}
把线程中的else去掉,再测试就可以了。
Old_Rookie_Su 2017-06-21
  • 打赏
  • 举报
回复
很简单嘛。 if(flag) { wait(); } 在这里wait了,另一个线程唤醒它后,它就跳过了这一次打印继续执行。改为 if (flag) { wait(); System.out.print(s); } else// 为假时进入
anlian523 2017-06-21
  • 打赏
  • 举报
回复
求助大神讲解一下啊
anlian523 2017-06-21
  • 打赏
  • 举报
回复
引用 5 楼 qq_26508409 的回复:
 public synchronized void printNumber(String s)
    {
        try
        {
            if(!flag)
            {
                wait();
            }
            else//为真时进入
            {
                System.out.print(s);
                flag=false;
                notifyAll();
            }
        }
        catch(InterruptedException ex)
        {
            ex.printStackTrace();
        }
    }
就拿这段来说,比如传3的时候wait(),你觉得线程唤醒之后走什么?不可能去走else的
好像有点懂了,就是进入方法要么是只执行if,要么只执行else,但是进入if后,if代码块只有wait,唤醒后也就没有别的操作了,是这样吧
anlian523 2017-06-20
  • 打赏
  • 举报
回复
多执行几次,有时候会这种情况,但是还是循环只执行13次 12A34B56D910F1314H1718J2122L2526N2930P3334R3738T4142V4546X4950Z

50,543

社区成员

发帖
与我相关
我的任务
社区描述
Java相关技术讨论
javaspring bootspring cloud 技术论坛(原bbs)
社区管理员
  • Java相关社区
  • 小虚竹
  • 谙忆
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧