目前系统中有一个需求需要用到线程,
点击一个按钮,启动一个线程,处理相关业务(这个线程大概10个小时后结束),
当这个线程还没结束时,又点击这个按钮,又会启动一个线程,这样就重复了。当再次点击这个按钮时,如何判断前面那个线程是否已结束?
 

解决方案 »

  1.   

    Thread.activeCount()
    判断当前java进程线程数
      

  2.   

    正如前面的哥们所诉,可以设计标记,thread中有很多方法来检测是执行过,如:isAlive() ,getState() ,都可以取得线程状态,最好使用锁机制。over
      

  3.   

    不想用标记。
    thread中是有很多方法来检测是执行过,问题是如何得到之前运行的线程? 然后.isAlive()判断synchronized 只是让数据同步,两个线程还是会同时存在。我要的效果是,当第一个线程在运行时,第二个线程就不让启动
      

  4.   

    JDK6实现方案,还是代码实在,分全给我,谢谢!import java.util.concurrent.BlockingQueue;
    import java.util.concurrent.Callable;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Future;
    import java.util.concurrent.SynchronousQueue;
    import java.util.concurrent.ThreadPoolExecutor;
    import java.util.concurrent.TimeUnit;public class Test{
      private static final BlockingQueue queue=new SynchronousQueue();
      //  private static final BlockingQueue queue=new LinkedBlockingQueue(1);
      private static final ExecutorService threadpool=new ThreadPoolExecutor(1,1,0L,TimeUnit.MILLISECONDS,queue);  public static Future submit(final Object obj){
        return threadpool.submit(new Callable(){
          @Override
          public Object call() throws Exception{
            // TODO do your job here!
            System.out.println(obj);
            Thread.sleep(2000);
            return obj;
          }
        });
      }  public static void main(String...args) throws Exception{
        submit("You got it!");
        submit("You got it!");
        submit("You got it!");
      }
    }我给的代码默认只有一个任务在工作,之前的未完成自动会抛出异常,自己根据需要进行处理;注释掉的那行意思是允许有一个在等待,总体来说就是倒腾那个queue
    SynchronousQueue:0等待,必须先有取等待才允许提交任务;
    LinkedBlockingQueue:可以根据需要配置等待任务数。
      

  5.   


    不行啊  整个WEB应用 一到晚上会有好几个线程在跑批。至于有几个我不确定
      

  6.   

    zoeg  给出的思路是对的。用java的线程池,配合自带的队列,并设置队列是阻塞的,线程池回按队列中的线程顺序去执行,阻塞意味着第一个执行之后才会执行第2个
      

  7.   

    我去,赚点分不容易啊,有话你就不能一次性说完
    我就不解释了,自己看代码:import java.util.HashMap;
    import java.util.Map;
    import java.util.concurrent.BlockingQueue;
    import java.util.concurrent.Callable;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Future;
    import java.util.concurrent.LinkedBlockingQueue;
    import java.util.concurrent.ThreadPoolExecutor;
    import java.util.concurrent.TimeUnit;
    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReentrantLock;public class Test{
      private static final BlockingQueue queue=new LinkedBlockingQueue();
      private static final ExecutorService threadpool=new ThreadPoolExecutor(10,20,0L,TimeUnit.MILLISECONDS,queue);  public static Future submit(final String name,final Object obj){
        return threadpool.submit(new Callable(){
          @Override
          public Object call() throws Exception{
            // TODO do your job here!
            boolean lock=Token.tryLock(name);
            if(!lock) return null;
            try{
              System.out.println(obj);
              Thread.sleep(2000);
              return obj;
            }finally{
              Token.unlock(name);
            }
          }
        });
      }  public static void main(String...args) throws Exception{
        submit("t1","You got t1!");
        submit("t1","You got t1!");
        submit("t1","You got t1!");
        submit("t2","You got t2!");
        submit("t2","You got t2!");
        submit("t2","You got t2!");
        Thread.sleep(3000);
        submit("t1","You got t1!");
        submit("t1","You got t1!");
        submit("t1","You got t1!");
        submit("t2","You got t2!");
        submit("t2","You got t2!");
        submit("t2","You got t2!");
      }  public static class Token{
        private static final Lock lockme=new ReentrantLock();
        private static final Map<String,Lock> locks=new HashMap<String,Lock>();    public static boolean tryLock(String name){
          Lock lock=getLock(name);
          return lock.tryLock();
        }    public static void unlock(String name){
          Lock lock=getLock(name);
          lock.unlock();
        }    private static Lock getLock(String name){
          lockme.lock();
          try{
            Lock lock=locks.get(name);
            if(lock==null){
              lock=new ReentrantLock();
              locks.put(name,lock);
            }
            return lock;
          }finally{
            lockme.unlock();
          }
        }
      }
    }
      

  8.   

    其实应该在提交到线程之前就控制的,懒得弄了,主要就是Token类来完成你的需求,自己看着用吧
      

  9.   

    有很多方法,例如,
    第一种:你将这个按钮设置为不可用。
    第二种:利用socket,说明该端口被暂用,这种一般是整个客户端才会使用。
    Pserver = new ServerSocket(1001);
    Socket sock = new Socket("127.0.0.1", 1001);
    第三种:将线程设定为静态对象,判断是否为空!
      

  10.   

    单例模式,当此线程alive的时候不予执行下一个进程,完成后再执行
      

  11.   

    SynchronousQueue队列,第一个在执行时,不会让第二个执行,而是直接抛出异常。
    我11楼的代码是更通用的实现,能够同时控制多个任务,每个任务限制只能一个实例在执行,执行期间的重复请求被丢弃,任务按名字区分。建议的做法是一个任务一个Action类,任务名就自动用该类的className。
    楼主该结贴了!