java——线程(Thread,Runnable,Callable,Future)

在java中,编写多线程程序,主要有两种不同的方法

1. 继承类java.lang.Thread,然后覆盖掉run()方法就可以了,把希望运行的程序都写在run()方法中

2. 通过实现Runnable接口来编写线程,覆盖掉Runnable接口中的run()方法

public interface Runnable {
    /**
     * When an object implementing interface <code>Runnable</code> is used
     * to create a thread, starting the thread causes the object's
     * <code>run</code> method to be called in that separately executing
     * thread.
     * <p>
     * The general contract of the method <code>run</code> is that it may
     * take any action whatsoever.
     *
     * @see     java.lang.Thread#run()
     */
    public abstract void run();
}

上面的代码就是接口Runnable,其实Runnalbe只是定义了一个简单的抽象函数。

public
class Thread implements Runnable {
}

Thread是一个实现了接口Runnable的类,类中封装了很多的常用函数。因为java中并不支持多重继承,因此有些时候需要通过实现接口Runnable来编写多线程程序。

上图所示是java中线程的一些状态(图片来源:http://www.cnblogs.com/dolphin0520/p/3920357.html)。

线程的执行
创建对象,调用start()方法,线程会自动调用run()方法。当一个线程被启动后,程序控制立刻返回给调用方法,然后新线程和调用方法就开始并发地执行。
 

示例1:继承Thread类

public class MyThread {
    
    private static int j=0;
    
    class ThreadTest extends Thread{
        private int i;
        private int time;
        public ThreadTest(int i,int time){
            this.i=i;
            this.time = time;
        }
        public void run(){
            while(true){
                try{
                    Thread.sleep(time);  
                }catch(InterruptedException e){
                    e.printStackTrace();
                }
                j++;
                System.out.println("Thread"+i+": "+j);
            }
        }
    }
    


    public static void main(String[] args) {
        // TODO Auto-generated method stub
        MyThread mt = new MyThread();
        ThreadTest t1 = mt.new ThreadTest(1,1000);
        ThreadTest t2 = mt.new ThreadTest(2,2300);
        ThreadTest t3 = mt.new ThreadTest(3,3500);
        ThreadTest t4 = mt.new ThreadTest(4,2700);
        t1.start();
        t2.start();
        t3.start();
        t4.start();

    }

}

示例2:实现接口

public class ThreadRunnable {
    private static int j=0;
    public static void main(String[] args){
        new Thread(new Runnable(){
            public void run(){
                while(true){
                    try{
                        Thread.sleep(1000);  //休眠1000毫秒
                    }catch(InterruptedException e){
                        e.printStackTrace();
                    }
                    j++;
                    System.out.println("Thread1:"+j);
                }
            }
        }).start();
        new Thread(new Runnable(){
            public void run(){
                while(true){
                    try{
                        Thread.sleep(1000);  //休眠1000毫秒
                    }catch(InterruptedException e){
                        e.printStackTrace();
                    }
                    j++;
                    System.out.println("Thread2:"+j);
                }
            }
        }).start();
        new Thread(new Runnable(){
            public void run(){
                while(true){
                    try{
                        Thread.sleep(1000);  //休眠1000毫秒
                    }catch(InterruptedException e){
                        e.printStackTrace();
                    }
                    j--;
                    System.out.println("Thread3:"+j);
                }
            }
        }).start();
        new Thread(new Runnable(){
            public void run(){
                while(true){
                    try{
                        Thread.sleep(1000);  //休眠1000毫秒
                    }catch(InterruptedException e){
                        e.printStackTrace();
                    }
                    j--;
                    System.out.println("Thread4:"+j);
                }
            }
        }).start();
    }
    
}

 有返回值的线程

在java 5 之前,线程都是没有返回值的,而Callable的出现使线程也可以返回一个结果了。

import java.util.concurrent.Callable;  

上面显示的是Callable所在的包,Callable的接口代码如下

@FunctionalInterface
public interface Callable<V> {
    /**
     * Computes a result, or throws an exception if unable to do so.
     *
     * @return computed result
     * @throws Exception if unable to compute a result
     */
    V call() throws Exception;
}

首先需要新建一个类,实现Callable接口

package threadOperation;

import java.util.concurrent.Callable;

public class MyCallable implements Callable{

private String id;
MyCallable(String id){
this.id = id;
}

@Override
public Object call() throws Exception {
// TODO Auto-generated method stub
return "this is the test of: "+id;
}

}

之后建立一个类,来测试MyCallable类的返回值

package threadOperation;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class CallableTest {

    public static void main(String[] args) throws InterruptedException, ExecutionException {
        // TODO Auto-generated method stub
        ExecutorService pool = Executors.newFixedThreadPool(3);  //thread pool
        Callable c1 = new MyCallable("first thread");
        Callable c2 = new MyCallable("second thread");
        Callable c3 = new MyCallable("third thread");
        
        Future f1 = pool.submit(c1);      //提交线程池执行
        Future f2 = pool.submit(c2);
        Future f3 = pool.submit(c3);
        
        System.out.println(f1.get().toString());
        System.out.println(f2.get().toString());
        System.out.println(f3.get().toString());

    }

}

这里面用到了线程池和Future这个接口,Future接口可以通过get操作来返回一个泛型的类

 

posted @ 2017-08-28 17:41  东木刀纹  阅读(282)  评论(0编辑  收藏  举报