日期:2014-05-20  浏览次数:20660 次

请问如何让一个方法同时只有2个线程在调用.
比如下面这个类
class test{
public void methodA(){
 //methodA同时有多个线程在访问,请问如何填充这个方法,使最多只有2个线程调用methodB,当调用完成后,其他那些方法才能继续调用
  methodB();

}
private void methodB(){

}

------解决方案--------------------
Java code

/**
 * ThreadNoneSync.java
 * 演示非同步线程访问共享数据带来的问题
 * @ kahn178
 * @ version 1.0
 * create on 2008-10-29
 */

package ThreadNoneSync;

import javax.microedition.midlet.MIDlet;
import javax.microedition.midlet.MIDletStateChangeException;

public class ThreadNoneSync extends MIDlet {
    boolean isRunning=true;
    int a=0;//共享数据
    
    //MIDLet对象实例的引用
    ThreadNoneSync instance=this;

    public ThreadNoneSync() {
        
        // TODO 自动生成构造函数存根
        super();
        
        //启动线程同进访问共享变量a
        new Thread("Thread Add"){
            public void run(){
                //对a进行加1运算
                while(isRunning){
                    String name=Thread.currentThread().getName();
                    synchronized(instance){ //进行线程的处理,监视器,线程访问时,会加一个锁。避免多线程访问共享数据造成破坏
                    System.out.print(name + ": " + a);
                    System.out.println("+1=" +  ++a);
                    }

                }
            }
        }.start();
        
      //启动线程同进访问共享变量a
        new Thread("Thread Add"){
            public void run(){
                
       //对a进行减1运算
        while(isRunning){
            String name=Thread.currentThread().getName();
            synchronized(instance){//会耗费系统资源,降低程序执行效率。因此一定在需要时才使用
            System.out.print(name + ": " +a );
            System.out.println("-1="+ --a);
            }
        }
        }
        }.start();
    }
    

    protected void startApp() throws MIDletStateChangeException {
        // TODO 自动生成方法存根

    }
    
    protected void pauseApp() {
        // TODO 自动生成方法存根

    }



    protected void destroyApp(boolean arg0) throws MIDletStateChangeException {
        // TODO 自动生成方法存根
  
        isRunning=false;
    }


}

------解决方案--------------------
Java code
package sample.concurrent;

import java.util.concurrent.Semaphore;

public class Test {

    private final Semaphore available = new Semaphore(2);

    public void methodA() {
        try {
            available.acquire();
            methodB();
            available.release();
        } catch (InterruptedException ex) {
        }
    }

    public void methodB() {
        System.out.println(Thread.currentThread().getName() + ": " + "Entering methodB ...");
        try {
            Thread.sleep(3000);
        } catch (InterruptedException ex) {
        }
        System.out.println(Thread.currentThread().getName() + ": " + "Leaving methodB ...");
    }

    public static void main(String[] args) {
        final Test t = new Test();
        for (int i = 0; i < 10; i++) {
            new Thread() {
                @Override
                public void run() {
                    t.methodA();
                }
            }.start();
        }
    }
}