关闭

java线程学习笔记(一)

319人阅读 评论(0) 收藏 举报
分类:

        在JAVA中如果一个程序开始运行,那么至少有2个线程,一个是我们熟悉的main线程,而另外一个则是JVM的垃圾回收器,实际上每启动一个程序都会建立一个JVM,即一个进程,而如果我们想在主线程之外建立一个新的线程,而不影响主线程的运行,这时我们有三种实现方式,以下是我的一些学习心得。

    (一)java中线程的实现方式

      在java实现一个线程的方式有三种,一种是继承Thread类,另外一种是实现Runnable接口,还有就是使用Callable和Future创建线程,其中,前两种方式的原理都是重新下run方法,一般来说实现Runnable接口比继承Thread类更加具有优势,主要原因有以下二点;

      1.实现Runnable接口可以避免java单继承的限制,从而可以便于类的扩展;

      2.在需要实现若干功能逻辑相同的线程时,采用实现Runnable的方式,可以有效的提高代码的重用性,避免代码的冗余,便于资源的共享。

      以下是具体的代码的例子,实现Runnable接口的例子:

public class FristThread implements Runnable{


int countNum = 5 ;

    public void run() {
       
    for(int i = 0 ; i < 5 ; i++){
    
    if(countNum > 0 ){
    
    System.out.println(Thread.currentThread().getName()+"-----> countNum  is --->" + countNum--);
    }
    
    }
    }
}


    主函数的测试代码为:

 public static void main(String[] args){
  
  FristThread thread1 = new FristThread();
  Thread h1=new Thread(thread1,"A");
  Thread h2=new Thread(thread1,"B");
  Thread h3=new Thread(thread1,"C");
  h1.start();
  h2.start();
  h3.start();

}


  

可以看到执行的结果为:

B-----> countNum  is --->5
B-----> countNum  is --->4
B-----> countNum  is --->3
A-----> countNum  is --->2
C-----> countNum  is --->1

而采用继承Thread的方式的实现代码为:

public class FristThread extends Thread {
int countNum = 5;
@Override
public void run() {
super.run();
for (int i = 0; i < 5; i++) {
  if(countNum > 0 ){
    
    System.out.println(Thread.currentThread().getName()+"-----> countNum  is --->" + countNum--);
    }
}
}
}


主函数测试代码:

public static void main(String[] args){

FristThread thread1 = new FristThread();
FristThread thread2 = new FristThread();
FristThread thread3 = new FristThread();
thread1.start();
thread2.start();
thread3.start();
}


可以看到运行结果为:

Thread-1-----> countNum  is --->5
Thread-1-----> countNum  is --->4
Thread-1-----> countNum  is --->3
Thread-1-----> countNum  is --->2
Thread-1-----> countNum  is --->1
Thread-0-----> countNum  is --->5
Thread-0-----> countNum  is --->4
Thread-0-----> countNum  is --->3
Thread-0-----> countNum  is --->2
Thread-0-----> countNum  is --->1
Thread-2-----> countNum  is --->5
Thread-2-----> countNum  is --->4
Thread-2-----> countNum  is --->3
Thread-2-----> countNum  is --->2
Thread-2-----> countNum  is --->1

   从上面的运行结果我们可以看到,通过实现Runnable接口的方式实现线程,可以实现公共的资源的共享。

   在这里还需要注意的是启动线程只能通过调用线程的start的方法,而调用run方法,只是相当于调用该类的一个方法。

 最后的一种实现方式是使用Callable和Future创建线程

  从java5开始,JDK提供了callable接口,java API提供的介绍是这样的:Callable 接口类似于 Runnable,两者都是为那些其实例可能被另一个线程执行的类设计的。但是Runnable 不会返回结果,并且无法抛出经过检查的异常,callable接口提供了一个call方法,这个方法相当于Runnable的run方法,Future接口表示异步计算的结果,它提供了检查计算是否完成的方法,以及等待计算的完成,并获取计算的结果,我们在使用它时常常使用的是,它的实现类FutureTask,FutrueTask类提供了对Future 的基本实现。仅在计算完成时才能获取结果;如果计算尚未完成,则阻塞 get 方法。一旦计算完成,就不能再重新开始或取消计算。可以用FutureTask来包装callable接口或者Runnable接口,因为FutureTask接口实现了Runnable,所以我们可以把它提供给Executor 执行,同样的道理,因为FutureTask实现了Runnable接口使用,可以在生成线程时把他当着Thread类构造函数的中的线程参数进行传入。

   以下是一个简单的应用实例:

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;


public class CallableTest implements Callable<Integer>{

	public static void main(String[] args) {
		
		/** 
		 * 生成一个callable实现类的对象,这个实现类包含了一个call方法,这个call方法
		 * 相当于Runnable的run方法,是线程的具体任务。
		 */
		CallableTest callableTest=new CallableTest();
		/**
		 * 使用FutureTask对象来包装callable实现对象,该FutureTask对象
		 * 实际上就是封装了callable类的call方法的返回结果
		 */
		FutureTask<Integer> futureTask=new FutureTask<Integer>(callableTest);
		/**
		 * 使用futureTask创建线程
		 */
		new Thread(futureTask, "futureTask").start();
		
		try {
			
			System.out.println("子线程执行完成并且返回 : "+futureTask.get());
			
		} catch (InterruptedException e) {
			e.printStackTrace();
		} catch (ExecutionException e) {
			e.printStackTrace();
		}
	}
	@Override
	public Integer call() throws Exception {
		
		int i = 0;
		for( ;i < 5 ; i++ ){
			System.out.println("子线程循环-----i = " + i);
		}
		return i;
	}
}
执行结果为:

子线程循环-----i = 0
子线程循环-----i = 1
子线程循环-----i = 2
子线程循环-----i = 3
子线程循环-----i = 4
子线程执行完成并且返回 : 5

以上是三种线程的实现方式,详细的介绍可以参考JDK API进行查询。



0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:2453次
    • 积分:121
    • 等级:
    • 排名:千里之外
    • 原创:10篇
    • 转载:0篇
    • 译文:0篇
    • 评论:0条
    文章分类