疯狂java


您现在的位置: 疯狂软件 >> 新闻资讯 >> 正文

Java线程的实现方式


 

  多线程一直给大家一种很难的感觉,其实接触了解之后你会发现,没有大家想的那么深奥,接下来我会分享我学习多线程的经历给大家,下面先简单的介绍下实现线程的三种方式:

  1、继承Thread

  (1)定义Thread类的子类,并重写该类的run方法,该方法的方法体就代表了线程需要完成的任务。可以把run方法称为线程执行体。

  (2)创建Thread子类的实例,即创建了线程对象。

  (3)调用线程对象的start方法来启动线程。

  package com.xiaomo.thread;

  public class ExtendThread extends Thread {

  private int i;

  public void run() {

  // 当线程继承Thread类时,直接使用this即可获取当前线程

  // Thread对象的getName()返回当前线程的名字

  // 因此可以直接调用getName()方法返回当前线程的名字

  for (; i < 100; i++) {

  System.out.println(this.getName() + " " + i);

  }

  }

  public static void main(String[] args) {

  for (int i = 0; i < 100; i++) {

  // 调用Thread的currentThread()方法获取当前线程

  System.out.println(Thread.currentThread()。getName() + " " + i);

  if (i == 20) {

  // 创建并启动第一个线程

  new ExtendThread()。start();

  // 创建并启动第二个线程

  new ExtendThread()。start();

  }

  }

  }

  }

  结果:

  main 0

  main 1

  .

  .

  main 19

  main 20

  Thread-0 0

  Thread-0 1

  .

  .

  Thread-0 21

  Thread-0 22

  .

  .

  Thread-1 98

  Thread-1 99

  继承Thread类的实现类不共享实例属性。

  2、实现Runnable

  (1)定义Runnable接口的实现类,并重写该接口的run方法,该方法的方法体就是该线程的线程执行体。

  (2)创建Runnable实现类的实例,并以此实例作为Thread的target来创建Thread对象,该Thread对象才是真正的线程对象。

  (3)调用线程对象的start方法来启动该线程。

  package com.xiaomo.thread;

  public class ImplRunnable implements Runnable {

  private int i;

  public static void main(String[] args) {

  for (int i = 0; i < 100; i++){

  System.out.println(Thread.currentThread()。getName()+" "+i);

  if(i == 20){

  ImplRunnable ir = new ImplRunnable();

  new Thread(ir,"线程一")。start();

  new Thread(ir,"线程二")。start();

  }

  }

  }

  @Override

  public void run() {

  for (; i < 100; i++) {

  // 当线程实现Runnable接口时

  // 如果想获得当前线程,只能用Thread.currentThread()方法

  System.out.println(Thread.currentThread()。getName() + " " + i);

  }

  }

  }

  结果:

  main 0

  main 1

  main 2

  .

  .

  .

  main 19

  main 20

  线程一 0

  线程一 1

  .

  .

  .

  线程一 70

  线程二 72

  main 46

  线程二 74

  线程一 73

  线程二 75

  .

  .

  .

  线程一 79

  main 98

  main 99

  实现Runnable类的实现类共享实例属性。

  3、使用Callable和Future创建线程

  (1)创建Callable接口的实现类,并实现cal方法,该call方法将作为线程执行体,且该call方法有返回值。

  (2)创建Callable实现类的实例,使用FutureTask类来包装Callable对象,该FutureTask对象封装了该Callable对象的call方法的返回值。

  (3)使用FutureTask对象作为Thread对象的target创建并启动新线程。

  (4)调用FutureTask对象的get方法来获取子线程执行结束后的返回值。

  package com.xiaomo.thread;

  import java.util.concurrent.Callable;

  import java.util.concurrent.FutureTask;

  public class ImplCallable implements Callable {

  public static void main(String[] args) {

  //创建Callable对象

  ImplCallable ic = new ImplCallable();

  //使用FutureTask来包装Callable对象

  FutureTask task = new FutureTask<>(ic);

  for (int i = 0; i < 100; i++) {

  System.out.println(Thread.currentThread()。getName()+" "+i);

  if(i == 20){

  //实质还是以Callable对象来创建并启动线程

  new Thread(task, "有返回值的线程")。start();

  }

  }

  try{

  //获取线程返回值

  System.out.println("子线程的返回值:"+task.get());

  }catch(Exception ex){

  ex.printStackTrace();

  }

  }

  //实现call()方法,作为线程执行体

  @Override

  public Integer call() throws Exception {

  int i = 0;

  for (; i < 100; i++) {

  System.out.println(Thread.currentThread()。getName() + " " + i);

  }

  //call方法可以有返回值

  return i;

  }

  }

  结果:

  main 0

  main 1

  .

  .

  main 33

  有返回值的线程 0

  有返回值的线程 1

  有返回值的线程 2

  .

  .

  有返回值的线程 98

  有返回值的线程 99

  main 34

  .

  .

  main 99

  子线程的返回值:100

  该方式可以获取返回值。