多线程知识点

一、创建新执行线程有两种方法:

 

① 一种方法是将类声明为 Thread 的子类。该子类应重写 Thread 类的 run 方法。创建对象,开启线程使用start关键字

    public static void main(String[] args) {
        //创建线程对象
        MyThread mt=new MyThread();
        //开启线程
        mt.start();
        //
        for(int i=0;i<100;i++){
            System.out.println(Thread.currentThread().getName()+":"+i);
        }
    }
public class MyThread extends Thread  {
    //描述线程任务
    public void run(){   //这个地方必须是run关键字 使用别的关键字会报错
        for(int i=0;i<100;i++){
            System.out.println(Thread.currentThread().getName()+":"+i);
        }
    }
}

还可以用线程匿名内部类来实现;

public static void main(String[] args) {
         //继承thread类
         Thread th = new Thread() {
         public void run() {
         for(int i=0;i<20;i++){
         System.out.println(Thread.currentThread().getName()+":"+i);
             }
           }
         };
         //开启线程
         th.start();
    }

②另一种方法是声明一个实现 Runnable 接口的类。该类然后实现 run 方法。然后创建Runnable的子类对象,传入到某个线程的构造方法中,开启线程。

public class MyRunnable implements Runnable{ //继承runnable
    public void run() {
        for(int i=0;i<100;i++){
            System.out.println(Thread.currentThread().getName()+":"+i);
        }
    }
}
    public static void main(String[] args) {
        // 创建线程任务
        MyRunnable mr=new MyRunnable();
        //创建线程对象并明确线程任务
        Thread th=new Thread(mr);
        //开启线程
        th.start();
        //描述主线程任务
        for(int i=0;i<100;i++){
            System.out.println(Thread.currentThread().getName()+":"+i);
        }
    }

同样可以用线程匿名内部类来实现;

    public static void main(String[] args) {
        Runnable my = new Runnable() {
            public void run() {
                for (int i = 0; i < 10; i++) {
                    System.out.println(Thread.currentThread().getName() + ":" + i);
                }
            }
        };
        Thread th = new Thread(my);
        th.start();
    }

 二、线程池

线程池主要用来解决线程生命周期开销问题和资源不足问题;

使用线程池关键字 :Runnable 接口 和 Callable接口

以Callable接口为例介绍;

public class MyCallable implements Callable<String>{  
    public String call() throws Exception {
        //
        return "abc";
    }    
}
    public static void main(String[] args) {
        //创建线程任务对象
        MyRunnaber02 mr=new MyRunnaber02(); 
        //获取线程池对象
        ExecutorService es=Executors.newFixedThreadPool(2);  
        //调用mr线程任务        
        es.submit(mr);
        es.submit(mr);
        //销毁线程池
        es.shutdown();
    }

 

 

练习:异步计算,2个线程,1个计算10的阶乘,一个计算20的阶乘并返回;

public class JiSuan implements Callable<Long>{      由于20的阶乘比较大 使用integer泛型会溢出
    private int num;
    public JiSuan(int num){
        this.num=num;
    }
    public Long call() throws Exception {
        long sum=1;
        for(int i=1;i<=num;i++){
            sum=sum*i;
        }
        return (long) sum;
    }
}
    public static void main(String[] args) throws InterruptedException, ExecutionException {
        JiSuan js1=new JiSuan(10);
        JiSuan js2=new JiSuan(20);
        //创建线程池
        ExecutorService ex=Executors.newFixedThreadPool(2);
        //执行任务
        Future<Long> f1=ex.submit(js1);
        Future<Long> f2=ex.submit(js2);
        System.out.println(f1.get()+"...."+f2.get());
    }

 

 

 此 练习充分运用了线程池的原理;可能会有更简单方法 欢迎各位大神指点和评论;

posted @ 2020-04-25 16:44  丿狂奔的蜗牛  阅读(84)  评论(0编辑  收藏  举报