`
lggege
  • 浏览: 375523 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

eclipse中的线程

    博客分类:
  • RCP
阅读更多
见: http://www.eclipseworld.org/bbs/read-cec-tid-1804.html

确实是好文章, 收藏一下. 

寒假我就上网很少了,真的非常不好意思.eclipse中的线程是开发eclipse插件中一个比较重要的基础,而很多书上都没有说,我最后抽时间写了这篇入门文章,希望对大家有帮助.

我先大致讲一讲GUI程序中的线程.
    虽然各个操作系统之间的线程机制是不一样的,但是大致是相同的.当用户使用GUI程序时,如果点鼠标或按下键盘上的键等时,操作系统会产生对应的GUI事件,它来决定哪个窗口或程序来接受每一个事件并且放到程序的事件队列中.
    任何GUI程序的底层结构就是一个事件循环.程序首先初始化事件循环,并开始循环,这个循环会从事件队列依次接收GUI事件并一一做出相应的反应.程序应该对事件做出快速的反应使程序一直对用户有响应,举个例子,用户点了一下程序里的一个按钮结果程序就没反应了,那么这个程序应该算是一个失败的程序吧.
    如果某个UI事件引发了某个需要长时间的事务,那么应该把它放到一个另外的单独的线程中,这样程序的那个事件循环就能够马上回来响应用户的下一个操作.线程是非常复杂的一个主题,如果处理的不好很容易造成死锁等很糟糕的情况.

    还好,eclipse为我们开发插件提供了一个方便的UI线程包,大大的简化了很多底层复杂的东西.先看看几个简单的概念.
1.SWT UI线程
SWT用的是操作系统直接支持的线程模式,程序会在主程序里运行一个时间循环并依次在这个线程里响应事件.看下面这段代码,UI线程就是创建Display的那个线程.
public static void main (String [] args) {
    Display display = new Display ();
    Shell shell = new Shell (display);
    shell.open ();
    // 开始事件循环
    // 关掉窗口后
    while (!shell.isDisposed ()) {
      if (!display.readAndDispatch ())
        display.sleep ();
    }
    display.dispose ();
  }

简单的小程序里,一个UI线程就能够满足需要了.
但如果是长时间的操作,你就最好不要用UI线程来做这些事,可以交给Job去做.它其实就是另外启动的线程,也就是等会我要说的非UI线程.

2.Job
Job类由org.eclipse.core.runtime插件提供.它能够让客户程序员轻松的在另外的线程中执行代码.
看一个小例子
Job job = new Job("My First Job") {
  protected IStatus run(IProgressMonitor monitor) {
      System.out.println("Hello World (from a background job)");
      return Status.OK_STATUS;
    }
  };
job.setPriority(Job.SHORT);
job.schedule(); // start as soon as possible

Job的默认优先级是Job.Long,这里例子中的优先级要比它高.
只要调用Job#schedule(),它就会尽快在另外的线程中运行run()中的代码.
再看一个小例子:
final Job job = new Job("Long Running Job") {
    protected IStatus run(IProgressMonitor monitor) {
      try {
        while(hasMoreWorkToDo()) {
          // do some work
          // ...
        if (monitor.isCanceled()) return Status.CANCEL_STATUS;
        }
        return Status.OK_STATUS;
      } finally {
        schedule(60000); // start again in an hour
      }
    }
  };
job.addJobChangeListener(new JobChangeAdapter() {
    public void done(IJobChangeEvent event) {
    if (event.getResult().isOK())
      postMessage("Job completed successfully");
      else
        postError("Job did not complete successfully");
    }
  });
job.setSystem(true);
  job.schedule(); // start as soon as possible

monitor 是一个进度显示条,它会在运行job时自动显示,如果任务成功运行完成,返回Status.OK_STATUS,如果中途被用户在进度显示条那里中断,就返回Status.CANCEL_STATUS.上面schedule(60000);它是让job每过1小时就自动运行,Job又一个非常强大的功能.
然后后面是可以给job添加监听器.
job.setSystem(true);这一句是把这个job设置为系统级别的.如果调用setUser(true),那么就被定义为用户级别的,用户级别和默认级别的job
    在运行时会以UI形式反映出来,如果是用户job,那么会弹出一个进度显示窗口,能让用户选择在后台里运行.
下图是一个job自动运行时的效果:

再介绍job常常用到的一个方法Job#join().
系统调用到某个job,调用它的run()方法:
再看下面这个例子:

  class TrivialJob extends Job {
    public TrivialJob() {
      super("Trivial Job");
    }
    public IStatus run(IProgressMonitor monitor) {
      System.out.println("This is a job");
      return Status.OK_STATUS;
    }
  }

  job的创建和计划如下所示:

  TrivialJob job = new TrivialJob();
  System.out.println("About to schedule a job");
  job.schedule();
  System.out.println("Finished scheduling a job");

  他们的执行是和时间没关系的,输出可能如下:
  About to schedule a job
  This is a job
  Finished scheduling a job

也可能是:

  About to schedule a job
  Finished scheduling a job
  This is a job


  如果希望某个job运行完成后在继续时,可以使用join()方法.
  join()会一直阻塞到该job运行完.

例子:
  TrivialJob job = new TrivialJob();
  System.out.println("About to schedule a job");
  job.schedule();
  job.join();
  if (job.getResult().isOk())
    System.out.println("Job completed with success");
  else
    System.out.println("Job did not complete successfully");

上面的代码执行后,输出应该就是这样:

  About to schedule a job
  This is a job
  Job completed with success

Job的功能是很强大的,还有很多功能我以后会介绍,也可以查阅官方帮助文档.这里先把几个常用的问题解决掉.
参见:
http://help.eclipse.org/help30/index.jsp?topic=/org.eclipse.platform.doc.isv/guide/runtime_jobs.htm

3.如果在Job中加上改变UI的代码就会失败.
原因如下:
如果是在非UI线程中调用UI,SWT就会抛出一个SWTException.
要在一个非UI线程改变UI的话有几种技术:

第一种,用:
Display#syncExec(Runnable)或
Diaplay#asyncExec(Runnable)

第二种:
已经开发了另外一种Job,就是UIJob,可以直接在它里面运行改变UI的代码,其实它就是在SWT的asyncExec()方法里运行的.所有继承UIJob的类应

该覆写runInUIThread方法而不是run方法.

3.关于进度显示
在Jface中:
org.eclipse.jface.operations包定义了一些接口用来在进度条下运行长时间的任务.
可以参见:
http://help.eclipse.org/help30/index.jsp?topic=/org.eclipse.platform.doc.isv/guide/jface_operations.htm

在eclipse插件和RCP开发中:
用户级别的job是互操作性最强的,它不仅能够让用户用Cancel键取消job,而且可以在Detail中展示具体情况,但是注意:
Detail只会在下面两种方法中出现:
IProgressService#busyCursorWhile或
IProgressService#runInUI
1)IProgressService#busyCursorWhile的用法例子:
注意这里的run()中做些和UI无关的事.
IProgressService progressService = PlatformUI.getWorkbench().getProgressService();
  progressService.busyCursorWhile(new IRunnableWithProgress(){
    public void run(IProgressMonitor monitor) {
      //do non-UI work
    }
  });

效果:

2)IProgressService#runInUI的用法例子:
注意这里的run()中可以做些和UI有关的事.
progressService.runInUI(
    PlatformUI.getWorkbench().getProgressService(),
    new IRunnableWithProgress() {
      public void run(IProgressMonitor monitor) {
        //do UI work
      }
    },
    Platform.getWorkspace().getRoot());

效果:

这里最后一个参数可以是null,或者是这个操作的规则,在这里我们是设定运行这个UI操作时锁定工作台.
更加具体的可以参见:
http://help.eclipse.org/help30/index.jsp?topic=/org.eclipse.platform.doc.isv/guide/workbench_jobs.htm

另外,有少数时候,我们不想弹出一个进度条窗口,而是只在最底下的状态栏显示就可以了,很简单,写自己的Job类时,在构造方法里加上一句:
setUser(false);就可以了.
分享到:
评论

相关推荐

    eclipse项目java线程实例

    Java线程是多任务编程的核心概念,特别是在大型的、复杂的软件系统中,如Eclipse这样的集成开发环境(IDE)中的项目。在这个"Eclipse项目java线程实例"中,我们可以深入理解并实践Java线程的创建、管理和同步机制。 ...

    java 多线程 源码 Eclipse开发 小型程序

    本教程将基于Eclipse开发环境,通过源码解析来探讨如何创建和管理Java多线程,并在小型程序中应用这些概念。 首先,我们了解Java中创建线程的两种主要方式: 1. **实现Runnable接口**:创建一个类,实现Runnable...

    多线程 小球 运行程序(eclipse工程可导入)

    2. `Thread`类或`Runnable`实现:每个小球可能由一个单独的线程控制,线程中包含小球运动的逻辑。 3. `Sort`类或方法:负责处理小球的排序逻辑,可能涉及并发控制。 4. 主程序:初始化小球,创建并启动线程,处理...

    在Eclipse中调试程序

    在Eclipse这个强大的Java开发环境中,调试程序是开发者日常工作中不可或缺的部分。Eclipse提供了丰富的调试工具和功能,帮助我们理解代码的运行过程,定位并修复问题。以下将详细讲解如何在Eclipse中进行程序调试。 ...

    详解Eclipse中的Debug技术

    本文将深入探讨Eclipse中的Debug技术,帮助你掌握这个功能强大的工具,提高问题定位和修复效率。 一、理解Eclipse Debug模式 Eclipse的Debug模式允许开发者逐行执行代码,查看变量的实时状态,跟踪调用栈,以及中断...

    在Eclipse中使用weblogic图解

    在Eclipse中使用WebLogic是一项常见的任务,尤其对于Java开发者来说,这有助于在集成开发环境中部署和管理WebLogic服务器的应用程序。本篇文章将详细介绍如何在Eclipse中配置和使用WebLogic Server,以及相关的源码...

    vc多线程学习的例程,大家一起分享吧

    例程可能展示了如何正确地处理线程中的异常,防止程序崩溃。 7. **线程优先级**:通过设置线程的优先级,可以影响线程调度。`SetThreadPriority`函数可以用来改变线程的优先级,但过度使用可能导致优先级反转和饥饿...

    eclipse4.2中文补丁包

    3. **Java 7支持**:此版本开始,Eclipse正式支持Java 7的语言特性,如多线程的“fork/join”框架、类型推断和try-with-resources语句等。 4. **更好的插件集成**:Eclipse Juno增强了插件之间的通信和协作,使得...

    在Eclipse中使用debug(Eclipse调试常用技巧)

    在Eclipse中使用debug是软件开发中调试代码的一个重要环节,尤其对于Java开发者来说,Eclipse作为一个成熟的集成开发环境,提供了强大的调试工具和技巧。尽管图像内容无法直接查看,但是根据标题和描述,我们可以...

    在Eclipse中进行调试

    ### 在Eclipse中进行调试的关键知识点 #### Eclipse作为Java开发平台的重要性 - **Eclipse**:作为一款功能强大的开源集成开发环境(IDE),Eclipse广泛应用于Java开发领域,特别是对于初学者来说,它提供了一个...

    ATM代码在eclipse中运行

    总的来说,"ATM代码在Eclipse中运行"这个主题涵盖了从编程基础到高级应用的多个层面,包括但不限于Java编程、数据库交互、用户界面设计、多线程编程、安全性以及软件测试。理解和实践这些知识点,对于开发出功能完备...

    eclipse 下配置OpenMP包

    在本篇文章中,我们将深入探讨如何在Eclipse开发环境中配置并使用OpenMP(Open Multi-Processor)技术。OpenMP是一种广泛使用的多线程编程模型,主要用于简化并行编程任务,提高程序运行效率。通过在Eclipse中配置...

    模拟jdbc多线程竞争资源---【Eclipse项目】

    本项目“模拟jdbc多线程竞争资源---【Eclipse项目】”着重于探讨在多线程环境下,如何处理并发访问数据库时可能出现的资源竞争问题。下面将详细介绍这个项目中的关键知识点。 1. JDBC基础: JDBC是Java平台的标准...

    Eclipse插件开发问题

    这是因为`launch`方法是在新线程中执行,而不是在Eclipse的UI线程中。在非UI线程中直接操作UI组件会导致错误。为了解决这个问题,开发者可以使用`Display.asyncExec`来异步执行UI更新代码。这段代码确保了在Eclipse...

    在Eclipse中使用debug

    以下是 Eclipse 中一些常用的调试技巧: 1. 条件断点 条件断点顾名思义,就是一个有一定条件的断点,只有满足了用户设置的条件,代码才会在运行到断点处时停止。在断点处点击鼠标右键,选择最后一个"Breakpoint ...

    Eclipse 4.2 juno 中文语言包

    3. **代码编辑器增强**:包括自动完成、代码提示、语法高亮等,这些功能在4.2版本中得到了进一步加强,有助于快速编写和调试代码。 4. **改进的调试工具**:Juno 提供了更强大的调试界面和功能,例如多线程调试的...

    Eclipse中常见图标说明

    Eclipse是一款广泛使用的集成开发环境(IDE),尤其在Java编程中极为流行。Eclipse的界面包含了许多图标,这些图标有助于用户快速识别和理解项目结构、类关系和其他开发过程中的关键元素。以下是对Eclipse中常见图标...

    eclipse_3.7_中文包_eclipse_汉化包_eclipse_最新最全汉化包

    - **改进的调试器**:增强了多线程调试功能,提供更好的断点管理,以及对Java 7的支持。 - **Eclipse Juno Web Tools Platform (WTP)**:增强了对Java EE 6的支持,包括对Glassfish、Tomcat等应用服务器的优化。 ...

Global site tag (gtag.js) - Google Analytics