`
zhongkem
  • 浏览: 152592 次
  • 性别: Icon_minigender_1
  • 来自: 天津
社区版块
存档分类
最新评论

eclipse中的线程

阅读更多
寒假我就上网很少了,真的非常不好意思.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