3

スタックトレースで示されているように、インデックスが実際に範囲内にある場合、インデックスはどのように範囲外になる可能性がありますか?コンテキストは重要ではないかもしれませんが、Netbeansプラットフォーム上のIDE用のLuaパーサー/ VMに取り組んでおり、これは忍び寄り続けています。どうすればいいの?奇妙な並行性の問題?洞察を事前に感謝します。

java.lang.IndexOutOfBoundsException: Index: 14, Size: 16
    at java.util.ArrayList.rangeCheck(ArrayList.java:604)
    at java.util.ArrayList.get(ArrayList.java:382)
    at org.netbeans.lib.lexer.BatchTokenList.existingToken(BatchTokenList.java:197)
    at org.netbeans.lib.lexer.BatchTokenList.tokenOffset(BatchTokenList.java:150)
    at org.netbeans.api.lexer.TokenSequence.offset(TokenSequence.java:256)
    at com.MYDevelopers.LuaSupportCompiler.TokenManager.getTokenStart(TokenManager.java:230)
    at com.MYDevelopers.LuaSupportCompiler.CompilationUnit.getCurrentLocation(CompilationUnit.java:459)
    at com.MYDevelopers.LuaSupportCompiler.CompilationUnit.expressionImp(CompilationUnit.java:654)
    at com.MYDevelopers.LuaSupportCompiler.CompilationUnit.expression(CompilationUnit.java:647)
    at com.MYDevelopers.LuaSupportCompiler.CompilationUnit.RHSexpression(CompilationUnit.java:643)
    at com.MYDevelopers.LuaSupportCompiler.CompilationUnit.chunk(CompilationUnit.java:1004)
    at com.MYDevelopers.LuaSupportCompiler.CompilationUnit.compile(CompilationUnit.java:164)
    at com.MYDevelopers.LuaSupportCompiler.CompilationUnit.compileIfRequired(CompilationUnit.java:148)
    at com.MYDevelopers.LuaSupport.LuaProject.CompilationManagers.SourcesManager.compile(SourcesManager.java:222)
    at com.MYDevelopers.LuaSupport.LuaProject.CompilationManagers.SourcesManager.compileAndEvaluateIfRequired(SourcesManager.java:210)
    at com.MYDevelopers.LuaSupport.LuaProject.CompilationManagers.SourcesManager.addSourceManager(SourcesManager.java:113)
    at com.MYDevelopers.LuaSupport.LuaProject.CompilationManagers.SourcesManager.addDirectory(SourcesManager.java:106)
    at com.MYDevelopers.LuaSupport.LuaProject.CompilationManagers.SourcesManager.addBootDirectory(SourcesManager.java:80)
    at com.MYDevelopers.LuaSupport.LuaProject.CompilationManagers.SourcesManager.addBaseLibraries(SourcesManager.java:72)
    at com.MYDevelopers.LuaSupport.LuaProject.CompilationManagers.SourcesManager.<init>(SourcesManager.java:47)
    at com.MYDevelopers.LuaSupport.LuaProject.CompilationManagers.GlobalCompilationManager.addProjectDirectory(GlobalCompilationManager.java:76)
    at com.MYDevelopers.LuaSupport.LuaProject.LuaProject.getSourcesManager(LuaProject.java:309)
    at com.MYDevelopers.LuaSupport.LuaProject.LuaProject$ProjectOpenHookImpl.projectOpened(LuaProject.java:599)
    at org.netbeans.spi.project.ui.ProjectOpenedHook$1.projectOpened(ProjectOpenedHook.java:84)
[catch] at org.netbeans.modules.project.ui.OpenProjectList.notifyOpened(OpenProjectList.java:1138)
    at org.netbeans.modules.project.ui.OpenProjectList.access$1600(OpenProjectList.java:134)
    at org.netbeans.modules.project.ui.OpenProjectList$LoadOpenProjects.loadOnBackground(OpenProjectList.java:434)
    at org.netbeans.modules.project.ui.OpenProjectList$LoadOpenProjects.run(OpenProjectList.java:312)
    at org.openide.util.RequestProcessor$Task.run(RequestProcessor.java:1452)
    at org.openide.util.RequestProcessor$Processor.run(RequestProcessor.java:2032)
4

2 に答える 2

10

のソースを読むと、次のように実装されArrayListていることがわかります。rangeCheck

 private void rangeCheck(int index) {
   if (index >= size)
     throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
 }

だから私の推測は並行性に行くだけです。この例外をスローしながら、インデックスを小さくする他の明白な方法はありません。

例外がスローされた後、どういうわけかサイズが変化します。

  • 範囲を超えているリストからアイテムを取得しようとします
  • 同時に、別のスレッドが別の要素を追加sizeしているため、例外がスローされたときのサイズよりも大きくなります
  • 例外が最終的にレンダリングされます
于 2012-11-23T22:27:33.150 に答える
0

私にも同じ例外があり、sun.print.Win32MediaSizeその答えに助けられました。これは並行性の問題です。

ログ出力:

java.lang.IndexOutOfBoundsException: Index: 14, Size: 15
at java.util.ArrayList.rangeCheck(ArrayList.java:635)
at java.util.ArrayList.get(ArrayList.java:411)
at sun.print.Win32MediaSize.findMediaName(Win32PrintService.java:1742)
at sun.print.Win32PrintService.initMedia(Win32PrintService.java:418)
at sun.print.Win32PrintService.getSupportedAttributeValues(Win32PrintService.java:1367)
at sun.print.RasterPrinterJob.updatePageAttributes(RasterPrinterJob.java:548)
at sun.print.RasterPrinterJob.setPrintable(RasterPrinterJob.java:997)
at net.sf.jasperreports.engine.export.JRPrintServiceExporter.exportReport(JRPrintServiceExporter.java:467)
  • コンストラクターのpublic Win32MediaSize(String name, int dmPaper) 場合、スレッド1はに文字列を追加しますがwinStringTable、オブジェクトは追加しませんwinEnumTable
  • 次に、スレッド2がメソッドを呼び出すとfindMediaName、例外が発生しindexoutofboundsます。

以下のコード

package sun.print;

import java.util.ArrayList;

import javax.print.attribute.EnumSyntax;
import javax.print.attribute.standard.MediaSize;
import javax.print.attribute.standard.MediaSizeName;

class Win32MediaSize extends MediaSizeName {
    private static ArrayList winStringTable = new ArrayList();
    private static ArrayList winEnumTable = new ArrayList();
    private static MediaSize[] predefMedia;
    private int dmPaperID; // driver ID for this paper.

    private Win32MediaSize(int x) {
        super(x);

    }

    private synchronized static int nextValue(String name) {
      winStringTable.add(name);
      return (winStringTable.size()-1);
    }

    public static synchronized Win32MediaSize findMediaName(String paramString) {
        int i = winStringTable.indexOf(paramString);
        if (i != -1) {
            return ((Win32MediaSize) winEnumTable.get(i));
        }
        return null;
    }

    public static MediaSize[] getPredefMedia() {
        return predefMedia;
    }

    public Win32MediaSize(String name, int dmPaper) {
        super(nextValue(name));
        dmPaperID = dmPaper;
        winEnumTable.add(this);
    }

    private MediaSizeName[] getSuperEnumTable() {
      return (MediaSizeName[])super.getEnumValueTable();
    }

    static {
        Win32MediaSize localWin32MediaSize = new Win32MediaSize(-1);

        MediaSizeName[] arrayOfMediaSizeName = localWin32MediaSize
                .getSuperEnumTable();
        if (arrayOfMediaSizeName != null) {
            predefMedia = new MediaSize[arrayOfMediaSizeName.length];

            for (int i = 0; i < arrayOfMediaSizeName.length; ++i)
                predefMedia[i] = MediaSize
                        .getMediaSizeForName(arrayOfMediaSizeName[i]);
        }
    }

    int getDMPaper() {
        return dmPaperID;
    }

    protected String[] getStringTable() {
      String[] nameTable = new String[winStringTable.size()];
      return (String[])winStringTable.toArray(nameTable);
    }

    protected EnumSyntax[] getEnumValueTable() {
      MediaSizeName[] enumTable = new MediaSizeName[winEnumTable.size()];
      return (MediaSizeName[])winEnumTable.toArray(enumTable);
    }

    }

編集:

私はjavaprintapiを呼び出すために5スレッドで印刷システムを実行していますが、同じ例外が発生することがあります。私はここまで多くのことを研究しましたが、同意点がわかります。
printServiceを1スレッドだけで初期化することで問題を修正しました。ここに記録して、sun.print.Win32MediaSize上記のようにクラスに同時発生の問題があることを思い出させます。

于 2017-11-28T08:21:52.343 に答える