0

I have a class like,

Class A extends B {

   String test = "";
   String first = "";

   public void testMethod() {
      new Thread() {
         public void run() {
           testThreadMethod();
         }
      }.start();

   }

   public void testThreadMethod() {
     System.out.println(first + " " + test);
   }
}

The above class compiles fine. But in run time, the error is thrown in system.out.println() saying "invalid thread access".

Is there any wrong in the code. Accessing instance variables in multithread not allowed? Is there any way to access the instance variable inside the thread?

Thanks in advance.

EDITED NEW: To Reproduce the problem

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.part.ViewPart;

public class SWTView extends ViewPart{
    public static Display display;
    public static Shell shell;
    static Text sampleText;
    static String testField1 = "";
    static String firstField2 = "";
    public static void main(String[] args) {
        display = new Display();
        shell = new Shell(display);
        // Create a new Gridlayout with 2 columns 
        // where the 2 column do not have the 
        // same size
        GridLayout layout = new GridLayout(2, false);
        // set the layout of the shell
        shell.setLayout(layout);
        // Create a label and a button

        sampleText = new Text(shell, SWT.NONE);
        Label label = new Label(shell, SWT.NONE);
        label.setText("A label");
        Button button = new Button(shell, SWT.PUSH);
        button.setText("Press Me");

        // Create a new label that will spam two columns
        label = new Label(shell, SWT.BORDER);
        label.setText("This is a label");
        // Create new layout data
        GridData data = new GridData(GridData.FILL, 
                GridData.BEGINNING, true, false, 2, 1);
        label.setLayoutData(data);

        // Create a new label which is used as a separator
        label = new Label(shell, SWT.SEPARATOR | SWT.HORIZONTAL);
        // Create new layout data
        data = new GridData(GridData.FILL, GridData.BEGINNING, true,
                false, 2, 1);
        data.horizontalSpan=2;
        label.setLayoutData(data);

        // Create a right aligned button
        Button b = new Button(shell, SWT.PUSH);
        b.setText("New Button");
        b.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent e) {
                new Thread() {
                    public void run() {
                        printInstanceVariables();
                    }
                }.start();
                //showProgressBar() ---> // This is been implemented in another file which will shoe progress bar
            }
        });

        data = new GridData(GridData.END, GridData.BEGINNING, false,
                false, 2, 1);
        b.setLayoutData(data);


        shell.pack();
        shell.open();
        while (!shell.isDisposed()) {
            if (!display.readAndDispatch())
                display.sleep();
        }
        display.dispose();
    }

    public static void printInstanceVariables() {
        System.out.println("Text entered is :: " +sampleText.getText());
        System.out.println("test Field 1 is :: " + testField1);
        System.out.println("first Field 2 is :: " + firstField2);
    }


    @Override
    public void createPartControl(Composite arg0) {
        // TODO Auto-generated method stub

    }

    @Override
    public void setFocus() {
      shell.setFocus();
    }

} 

The above code will throw invalid thread acesses ecpection @ printInstanceVariables() first system.out.println()

Answer: Got it.. It is because of accessing the component Text inside the thread in printInstanceVariables(). When i pass this component as paramter, everything works fine. Thanks for all you answers.

13
  • sorry.. mistakenly typed at end of testmethod. Commented Jun 4, 2013 at 10:28
  • 1
    Try declaring test and first as final Commented Jun 4, 2013 at 10:33
  • 2
    Is there a stack trace with the error? Please post the entire error message. There isn't anything special that you must do to access instance fields from a thread. Commented Jun 4, 2013 at 10:34
  • 3
    @cmbaxter Why? There is no need. The program looks fine so the problem is in the code that has not been shown yet... Commented Jun 4, 2013 at 10:35
  • 1
    I tried it as well. Worked for me. Commented Jun 4, 2013 at 10:44

3 Answers 3

3

This program compiles and executes as expected (it prints a space and a new line). Your problem is somewhere else:

public class Test {

    public static void main(String[] args) throws Exception {
        A a = new A();
        a.testMethod();
    }

    static class A {

        String test = "";
        String first = "";

        public void testMethod() {
            new Thread() {
                public void run() {
                    testThreadMethod();
                }
            }.start();
        }

        public void testThreadMethod() {
            System.out.println(first + " " + test);
        }
    }
}
Sign up to request clarification or add additional context in comments.

1 Comment

Correct. I got the same result.
1

I tried your code without extending class B and its working fine. What does your class B contain? Is there really any need to extend class B?

3 Comments

Good question. @Rock123 - what does B look like?
I am executing this class with SWT view part. the class B in question is the ViewPart class and class A is my view. The class A will be executed when the view is loaded and the new thread inside the class will be executed on click of a button in the view. Since class A is not executed by new Thread, the instance variables are not accessible in new thread??? please let me know on this.
@Rock123 The new Thread instance is an anonymous instance of A and therefore DOES have access to the fields of A. We have said this MULTIPLE times. Something ELSE is the issue.
-2

anonymous inner class is only allowed access FINAL member variable. this is JVM specification. i doubt why there is no warning when your code be compiled.


in fact i could get nothing out put when run these code. is there something wrong?


i rewrite the codes, test it and find enter image description here

it can't access a member variable when the thread in anonymous inner class. please see the output from eclipse.

enter image description here

1 Comment

I believe you are thinking of final parameters. This is not true of fields.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.