调用被阻塞线程的方法

时间:2016-04-03 03:48:03

标签: java multithreading

我刚刚开始学习Java中的多线程,我仍然在想一些事情。首先,扩展Thread的类是否有其他与之关联的实例方法可以在执行期间调用 - 如果是这样,它是否可以在执行期间更改线程的状态?其次,如果这个类被阻塞等待信号量,它的实例方法是否仍然可以被调用?像运行这两个线程的东西:

Thread1 t;
public class Thread1 extends Thread { 
    private int num;
    public run() {
        sem.acquire(); // here it blocks waiting for another thread 
                       //to call its setInt function and release it
        System.out.println("num is " + num);
    }
    public void setInt(int i) {
        num = i;
    }
}

public class Thread2 extends Thread {
    public run() {
        t.setInt(5);
        sem.release();
    }
}

2 个答案:

答案 0 :(得分:4)

这里有一些混乱。

  1. 主题没有方法。类有方法。
  2. 课程没有被阻止。线程被阻止。
  3. 您可以随时调用任何方法。方法本身可能是同步的,这将延迟进入它,或者它可能在内部使用同步,同上或信号量,同上。

答案 1 :(得分:0)

为了演示你在寻找什么,这是我测试过的代码示例:

package test2;

import java.util.concurrent.Semaphore;

public class mainclass {

    static Thread1 t;

    static Semaphore sem;

    static Semaphore sem_protect;

    public synchronized static void main (String[] args) {

         sem = new Semaphore(0);

         sem_protect = new Semaphore(1);

         t =  new Thread1();

         Thread1 th1 = new Thread1();
         th1.start();

         Thread2 th2 = new Thread2();
         th2.start();

         try {
             synchronized (th2){
            th2.wait();
             }
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

         System.out.println("The end !");
      }


    public static class Thread1 extends Thread { 

        private int num;

        public void run() {

            try {
                sem.acquire();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } // here it blocks waiting for another thread 
                           //to call its setInt function and release it
            try {
                sem_protect.acquire();
                System.out.println("num is " + num);
                sem_protect.release();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }


        }

        public synchronized void setInt(int i) {

            try {
                sem_protect.acquire();
                this.num = i;
                sem_protect.release();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }


            System.out.println("value of num is: "+num);
        }
    }

    public static class Thread2 extends Thread {
        public void run() {
            t.setInt(5);
            sem.release();
        }
    }

}

以下是执行此代码的结果:

value of num is: 5
The end !
num is 0

使用此结果,您可以看到仍然可以从Thread2访问类thread1的方法。它意味着您访问类实例的方法,没有线程的方法。 (这是你第一个问题的答案)

第一个线程的状态不会被第二个线程更改,num对于第一个线程仍为0,线程各有自己的上下文。

即使我们使用另一个信号量保护对num的访问权限,我们也没有两个线程的num值。