zoukankan      html  css  js  c++  java
  • NoSuchMethodError

    疯狂java第16章课后习题第一题:用java写两个线程,一个线程打印1-52,另一个线程打印字母A-Z,打印顺序为12A34B。。。5152Z。

    于是在Eclipse中根据第一个java文件自己敲出的第二个java文件,二者几乎没有什么区别,可是第一个文件运行成功并正确显示结果,第二个文件运行报错:NoSuchMethodError

    1.PrinterCheck.java

      1 import java.util.concurrent.locks.*;
      2 class Printer
      3 {
      4     private final Lock lock = new ReentrantLock();
      5     private final Condition cond = lock.newCondition();
      6     private final int[] arrNumber = new int[52];
      7     private int n;//arrNumber计数
      8     private final char[] arrChar = new char[26];
      9     private int c;//arrChar计数
     10     private int counter;//连续打印数字的间隔
     11     //Printer构造器
     12     public Printer( )
     13     {
     14         for(int i=0;i<arrNumber.length;i++)
     15         {
     16             arrNumber[i] = (i+1);
     17         }
     18         for(char i='A';i<'Z'+1;i++)
     19             
     20             
     21         {
     22             arrChar[i-65] = i;
     23         }
     24     }
     25     public void printNumber()
     26     {
     27         lock.lock();
     28         try
     29         {
     30             if(counter>1)
     31             {
     32                 cond.await();
     33             }
     34             else
     35             {    if(n>51) return;
     36                 System.out.print(arrNumber[n]+" ");
     37                                 n++;
     38                 counter++;
     39                 cond.signalAll();
     40             }
     41          
     42         }
     43         catch (InterruptedException e)
     44         {
     45             e.printStackTrace();
     46         }
     47         finally
     48         {
     49             lock.unlock();
     50         }
     51     }
     52     public void printChar()
     53     {
     54         lock.lock();
     55         try
     56         {
     57             if(counter<2)
     58             {
     59                 cond.await();
     60             }
     61             else
     62             {
     63                 if(c>25) return;
     64                 System.out.print(arrChar[c]+" ");
     65                 c++;
     66                 counter=0;
     67                 cond.signalAll();
     68             }
     69         }
     70         catch (InterruptedException e)
     71         {
     72             e.printStackTrace();
     73         }
     74         finally
     75         {
     76             lock.unlock();
     77         }
     78     }
     79 }
     80 class PrintNumber extends Thread
     81 {
     82     private Printer print;
     83     public PrintNumber(String name,Printer print)
     84     {
     85         super(name);
     86         this.print = print;
     87     }
     88     public void run()
     89     {
     90         for(int i=0;i<100;i++)
     91         {
     92             print.printNumber();
     93         }
     94     }
     95 }
     96 class PrintChar extends Thread
     97 {
     98     private Printer print;
     99     public PrintChar(String name,Printer print)
    100     {
    101         super(name);
    102         this.print = print;
    103     }
    104     public void run()
    105     {
    106         for(int i=0;i<100;i++)
    107         {
    108              print.printChar();
    109         }
    110     }
    111 }
    112 public class PrinterCheck
    113 {
    114     public static void main(String[] args) throws Exception  
    115     {
    116         Printer print = new Printer();
    117         new PrintNumber("打印数字",print).start();
    118         new PrintChar("打印字符",print).start();
    119     }
    120 }


    点击运行,结果如下:

    2.MulThreadPrint.java 

        

      1 import java.util.concurrent.locks.* ;
     2 class Printer
    3
    { //显示定义Lock对象 4 private final Lock lock = new ReentrantLock(); 5 //获得指定Lock对象对应的condition 6 private final Condition cond = lock.newCondition(); 7 //private final int[] arrNumber = new int[52];//保存数字的数组 8 private final int[] arrNumber = new int[52]; 9 private int nNumber;//数字的计数 10 //private final char[] arrChar = new char[26];//保存字符的数组 11 private final char[] arrChar = new char[26]; 12 private int nChar;//字符的计数 13 14 private int nInternal;//数字连续打印的间隔 15 //重写构造器对数组进行初始化赋值 16 public Printer() 17 { 18 for(int i=0;i<arrNumber.length;i++) 19 { 20 arrNumber[i] = i+1; 21 } 22 for(char i='A';i<'Z'+1;i++) 23 { 24 arrChar[i-65] = i; 25 } 26 } 27 //打印数字的方法 28 public void PrintNumber() 29 { //加锁 30 lock.lock(); 31 try 32 { //如果数字连续打印了2个,就暂停等待 33 if(nInternal>1) 34 { 35 cond.await(); 36 } 37 //如果数字连续打印少于2个,就继续打印,打印完数字之后就唤醒其他线程 38 else 39 {
    //判断到最后数字时返回退出程序
    40 if(nNumber==52) 41 return; 42 System.out.print(arrNumber[nNumber]+" "); 43 nNumber++; 44 nInternal++; 45 cond.signalAll(); 46 47 } 48 } 49 catch (InterruptedException ex) 50 { 51 ex.printStackTrace(); 52 } 53 //用finally块来释放锁 54 finally 55 { 56 lock.unlock(); 57 } 58 } 59 //打印字符的方法 60 public void PrintChar() 61 { 62 lock.lock(); 63 try 64 { 65 if(nInternal<2) 66 { 67 cond.await(); 68 } 69 else 70 {
    //判断到最后字符时返回退出程序
    71 if(nChar==26) 72 return; 73 System.out.print(arrChar[nChar]+" "); 74 nChar++; 75 nInternal = 0; 76 cond.signalAll(); 77 } 78 } 79 catch (InterruptedException ex) 80 { 81 ex.printStackTrace(); 82 } 83 //用finally块来释放锁 84 finally 85 { 86 lock.unlock(); 87 } 88 } 89 } 90 91 class PrintNumberThread extends Thread 92 { 93 private Printer Printer; 94 public PrintNumberThread(String name,Printer Printer) 95 { 96 super(name); 97 this.Printer = Printer; 98 } 99 public void run() 100 { //这里必须有for循环,不然只打印一轮 101 for(int i=0;i<100;i++) 102 { 103 Printer.PrintNumber(); 104 } 105 } 106 } 107 108 class PrintCharThread extends Thread 109 { 110 private Printer Printer; 111 public PrintCharThread(String name,Printer Printer) 112 { 113 super(name); 114 this.Printer = Printer; 115 } 116 public void run() 117 { 118 for(int i=0;i<100;i++) 119 { 120 Printer.PrintChar(); 121 } 122 } 123 } 124 125 public class MulThreadPrint 126 { 127 public static void main(String[] args) throws Exception 128 { 129 Printer Printer = new Printer(); 130 new PrintNumberThread("打印数字",Printer).start(); 131 new PrintCharThread("打印字符",Printer).start(); 132 } 133 }

    点击运行,结果如下:

    根据报错,是PrintNumberThread.run函数出错了,而run函数调用的是PrintNumber()函数。但实际上PrintNumber()函数是存在的。

    问题原因:因为两个文件在同一个包下,而且两个文件的Printer类重名了,于是得到两个矛盾的Printer.class。将第二个文件的Printer类改个名字,再运行即可得到正确结果。

    这里提供该题的第二种方法,同时也是最优方法:将ncouner去掉,直接以i%2==0来判断连续打印2个数字。

     1 class Printer2
     2 {  
     3      private final int[] arrNumber = new int[52];//保存数字的数组
     4      private final char[] arrChar = new char[26];//保存字符的数组
     5 
     6      //重写构造器对数组进行初始化赋值
     7      public Printer2()
     8      {
     9          for(int i=0;i<arrNumber.length;i++)
    10          {
    11              arrNumber[i] = i+1;
    12          }
    13          for(char i=0;i<arrChar.length;i++)
    14          {
    15              arrChar[i] = (char)('A'+i);
    16          }
    17      }
    18     //定义一个打印数字的同步方法
    19     public synchronized void PrintNumber()
    20     {
    21          for (int i = 1; i < arrNumber.length+1; i++) 
    22          {     //一开始就打印数字
    23                 System.out.print(arrNumber[i-1]+" "); 
    24                 try
    25                 {   //每连续打印两个数字后,数字线程就唤醒其他线程并且自己暂停等待
    26                     if(i%2 == 0)
    27                     {   
    28                         notifyAll();
    29                         wait();
    30                     }
    31                     
    32                 }
    33                 catch(Exception e)
    34                 {
    35                     e.printStackTrace(); 
    36                 }                                
    37         }
    38     }
    39     
    40     public synchronized void PrintChar()
    41     {
    42          for(int i=0;i<arrChar.length;i++)
    43          {   //一开始就打印字符
    44              System.out.print(arrChar[i]+" ");
    45              try
    46              {    //每打印一个字符之后,字符线程就唤醒其他线程并且自己暂停等待        
    47                   notifyAll();
    48                   wait();              
    49              }
    50              catch(Exception e)
    51              {
    52                   e.printStackTrace(); 
    53              }
    54          }
    55     }
    56 }
    57 //打印1-52
    58 class PrintThreadNumber extends Thread
    59 {
    60     private Printer2 Printer;
    61     public PrintThreadNumber(Printer2 Printer)
    62     {
    63         this.Printer = Printer;
    64     }
    65     public void run()
    66     {
    67         Printer.PrintNumber();
    68     }
    69 }
    70 //打印A-Z
    71 class PrintThreadChar extends Thread
    72 {
    73     private Printer2 Printer;
    74     public PrintThreadChar(Printer2 Printer)
    75     {
    76         this.Printer = Printer;
    77     }
    78     public void run()
    79     {
    80         Printer.PrintChar();     
    81     }
    82 } 
    83 
    84 
    85 public class MulThreadCom2
    86 {
    87     public static void main(String[] args) throws Exception 
    88     {
    89         Printer2 Printer = new Printer2(); 
    90         // 启动两个线程 
    91         PrintThreadNumber t1 = new PrintThreadNumber(Printer); 
    92         PrintThreadChar t2 = new PrintThreadChar(Printer); 
    93         t1.start(); 
    94         t2.start(); 
    95           
    96      }
    97 }
  • 相关阅读:
    E小press框架之第三步(参数接收)
    Express框架之第二步(路由)
    Express框架之第一步(创建工程)
    【排序】基数排序
    【数学】平方和公式$$sum_{i=1}^{n}i^2=frac{n(n+1)(2n+1)}{6}$$
    【博弈论】Nim游戏
    【搜索】对抗搜索【CF】J. Situation
    【图论】Kruskal算法
    dijkstra算法+堆优化 + 链式前向星版本
    【DP】【数位DP】
  • 原文地址:https://www.cnblogs.com/TTTTT/p/5823718.html
Copyright © 2011-2022 走看看