有关 java中 线程的问题!高手进

qkniit 2013-01-22 01:10:42
目前系统中有一个需求需要用到线程,
点击一个按钮,启动一个线程,处理相关业务(这个线程大概10个小时后结束),
当这个线程还没结束时,又点击这个按钮,又会启动一个线程,这样就重复了。

当再次点击这个按钮时,如何判断前面那个线程是否已结束?
...全文
441 17 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
zoeg 2013-01-24
  • 打赏
  • 举报
回复
引用 14 楼 qkniit 的回复:
引用 8 楼 duiduiaa 的回复:zoeg 给出的思路是对的。用java的线程池,配合自带的队列,并设置队列是阻塞的,线程池回按队列中的线程顺序去执行,阻塞意味着第一个执行之后才会执行第2个 我想让第二个 不执行
SynchronousQueue队列,第一个在执行时,不会让第二个执行,而是直接抛出异常。 我11楼的代码是更通用的实现,能够同时控制多个任务,每个任务限制只能一个实例在执行,执行期间的重复请求被丢弃,任务按名字区分。建议的做法是一个任务一个Action类,任务名就自动用该类的className。 楼主该结贴了!
rome_wu 2013-01-23
  • 打赏
  • 举报
回复
有很多方法,例如, 第一种:你将这个按钮设置为不可用。 第二种:利用socket,说明该端口被暂用,这种一般是整个客户端才会使用。 Pserver = new ServerSocket(1001); Socket sock = new Socket("127.0.0.1", 1001); 第三种:将线程设定为静态对象,判断是否为空!
zoeg 2013-01-23
  • 打赏
  • 举报
回复
其实应该在提交到线程之前就控制的,懒得弄了,主要就是Token类来完成你的需求,自己看着用吧
zoeg 2013-01-23
  • 打赏
  • 举报
回复
我去,赚点分不容易啊,有话你就不能一次性说完。。。 我就不解释了,自己看代码:

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();
      }
    }
  }
}
wenhaoxp1987 2013-01-23
  • 打赏
  • 举报
回复
单例模式,当此线程alive的时候不予执行下一个进程,完成后再执行
Curtain李志鹏 2013-01-23
  • 打赏
  • 举报
回复
照你的需求,我觉得可以试试单例+线程
qkniit 2013-01-23
  • 打赏
  • 举报
回复
引用 8 楼 duiduiaa 的回复:
zoeg 给出的思路是对的。用java的线程池,配合自带的队列,并设置队列是阻塞的,线程池回按队列中的线程顺序去执行,阻塞意味着第一个执行之后才会执行第2个
我想让第二个 不执行
_jerrytiger 2013-01-22
  • 打赏
  • 举报
回复
引用 7 楼 qkniit 的回复:
引用 6 楼 zoeg 的回复:我给的代码默认只有一个任务在工作,之前的未完成自动会抛出异常,自己根据需要进行处理;注释掉的那行意思是允许有一个在等待,总体来说就是倒腾那个queue SynchronousQueue:0等待,必须先有取等待才允许提交任务; LinkedBlockingQueue:可以根据需要配置等待任务数。 不行啊 整个WEB应用 一到晚上……
其他的线程你不用关心啊。 给这快功能 , 就单独用个线程池 , 其他的线程不要放到这个线程池里面。
龙泉剑 2013-01-22
  • 打赏
  • 举报
回复
这个很简单啊,直接用标志位不就行了
duiduiaa 2013-01-22
  • 打赏
  • 举报
回复
zoeg 给出的思路是对的。用java的线程池,配合自带的队列,并设置队列是阻塞的,线程池回按队列中的线程顺序去执行,阻塞意味着第一个执行之后才会执行第2个
qkniit 2013-01-22
  • 打赏
  • 举报
回复
引用 6 楼 zoeg 的回复:
我给的代码默认只有一个任务在工作,之前的未完成自动会抛出异常,自己根据需要进行处理;注释掉的那行意思是允许有一个在等待,总体来说就是倒腾那个queue SynchronousQueue:0等待,必须先有取等待才允许提交任务; LinkedBlockingQueue:可以根据需要配置等待任务数。
不行啊 整个WEB应用 一到晚上会有好几个线程在跑批。至于有几个我不确定
zoeg 2013-01-22
  • 打赏
  • 举报
回复
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:可以根据需要配置等待任务数。
tianfang 2013-01-22
  • 打赏
  • 举报
回复
单例线程,线程中有状态属性。获得线程后,检查线程状态
qkniit 2013-01-22
  • 打赏
  • 举报
回复
引用 3 楼 yfxvector 的回复:
正如前面的哥们所诉,可以设计标记,thread中有很多方法来检测是执行过,如:isAlive() ,getState() ,都可以取得线程状态,最好使用锁机制。over
不想用标记。 thread中是有很多方法来检测是执行过,问题是如何得到之前运行的线程? 然后.isAlive()判断 synchronized 只是让数据同步,两个线程还是会同时存在。 我要的效果是,当第一个线程在运行时,第二个线程就不让启动
胖名 2013-01-22
  • 打赏
  • 举报
回复
正如前面的哥们所诉,可以设计标记,thread中有很多方法来检测是执行过,如:isAlive() ,getState() ,都可以取得线程状态,最好使用锁机制。over
IceArmour 2013-01-22
  • 打赏
  • 举报
回复
Thread.activeCount() 判断当前java进程线程数
  • 打赏
  • 举报
回复
使用线程锁,或者设置标记都行。

67,550

社区成员

发帖
与我相关
我的任务
社区描述
J2EE只是Java企业应用。我们需要一个跨J2SE/WEB/EJB的微容器,保护我们的业务核心组件(中间件),以延续它的生命力,而不是依赖J2SE/J2EE版本。
社区管理员
  • Java EE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧