线程创建

喜夏-厌秋 提交于 2019-12-06 10:58:47

线程创建

三种创建方式:①Thread class  继承Thread类

                           ②Runnable接口  实现(implement)Runnable接口,Thread类就是实现了Runnable接口

                           ③Callable接口  实现Callable接口

Thread类

自定义线程类继承Thread类;重写run方法,编写程序执行体;创建线程对象,调用start方法启动线程。

package com.wang.thread;//创建线程方式一:继承Thread类,重写run方法,调用start方法开启线程public class ThreadDemo01 extends Thread{    @Override    public void run(){        //run方法线程体        for (int i = 0; i < 200; i++) {            System.out.println("我在"+i);        }    }    public static void main(String[] args) {        //main线程,主线程        //创建一个线程对象        ThreadDemo01 threadDemo01=new ThreadDemo01();        //调用start方法开启线程        threadDemo01.start();      //两条线程同时执行,交替执行        for (int i = 0; i < 2000; i++) {            System.out.println("我在学习多线程"+i);        }    }}

线程开启不一定立即执行,由cpu调度执行

案例:用多线程同时下载几个图片

分析:下载图片首先需要一个下载器,所以先写一个下载器,在下载器中写下载方法,通过FileUtils工具类的方法copyURLToFile,把URL变成一个文件,参数需要一个url和name。

实现线程类,继承Thread类,变成线程类,在类中重写run方法,run方法就是线程的执行体。

创建三个线程,通过start将三个线程同时启

package com.practice.thread;​import org.apache.commons.io.FileUtils;​import java.io.File;import java.io.IOException;import java.net.URL;//common.io是别人写好的,直接下载下来用​//练习thread,实现多线程同步下载图片public class ThreadDemo01 extends Thread {    private String url;//网络图片地址    private String name;//保存的文件名    public ThreadDemo01(String url,String name){        this.url=url;        this.name=name;    }    @Override    public void run() {//下载图片线程的执行体        WebDownloader webDownloader=new WebDownloader();        webDownloader.downloader(url,name);        System.out.println("下载了文件名为:"+name);    }​    public static void main(String[] args) {        ThreadDemo01 t1=new ThreadDemo01("http://pic.ruiwen.com/allimg/1708/598c8d3752d8939511.jpg?x-oss-process=style/qr.ruiwen","2.jpg");        ThreadDemo01 t2=new ThreadDemo01("http://pic.ruiwen.com/allimg/1708/598c8d37c8e9a56734.jpg?x-oss-process=style/qr.ruiwen","3.jpg");        ThreadDemo01 t3=new ThreadDemo01("https://gss1.bdstatic.com/-vo3dSag_xI4khGkpoWK1HF6hhy/baike/c0%3Dbaike150%2C5%2C5%2C150%2C50/sign=e90c38903ea85edfee81f671283d6246/3ac79f3df8dcd100ef9ca9e1788b4710b8122fe9.jpg","YIBO.jpg");​        t1.start();        t2.start();        t3.start();    }}//下载器class WebDownloader{    //下载方法    public void downloader(String url,String name){        try {            FileUtils.copyURLToFile(new URL(url),new File(name));//FileUtil文件工具包,copyURLToFile把网页地址变成一个文件        }catch(IOException e){            e.printStackTrace();            System.out.println("IO异常,downloader方法出现问题");        }    }}

实现Runnable

定义MyRunnable类实现Runnable接口;重写run方法,编写线程执行体;创建线程对象,调用start方法启动线程。

package com.wang.thread;//创建线程方式二:实现Runnable接口,重写run方法,执行线程需要丢入Runnable接口的实现类,调用startpublic class RunnableDemo01 implements Runnable{    @Override    public void run() {        for (int i = 0; i < 20; i++) {            System.out.println("我在"+i);        }    }​    public static void main(String[] args) {        //创建Runnable接口的实现类的对象        RunnableDemo01 runnableDemo01=new RunnableDemo01();        //创建线程对象,通过线程对象来开启我们的线程,代理        //Thread thread=new Thread(runnableDemo01);        //thread.start();        new Thread(runnableDemo01).start();        for (int i = 0; i < 1000; i++) {            System.out.println("我在学习多线程"+i);        }    }}

案例:用多线程同时下载几个图片

package com.practice.thread;​import org.apache.commons.io.FileUtils;​import java.io.File;import java.io.IOException;import java.net.URL;​public class RunnableDemo01 implements Runnable {    private String url;    private String name;    public RunnableDemo01(String url,String name){        this.url=url;        this.name=name;    }    @Override    public void run() {       WebDownloader downloader=new WebDownloader();       downloader.downloader(url,name);        System.out.println("下载了文件名为:"+name);    }​    public static void main(String[] args) {        RunnableDemo01 r1=new RunnableDemo01("http://pic.ruiwen.com/allimg/1708/598c8d3752d8939511.jpg?x-oss-process=style/qr.ruiwen","2.jpg");        RunnableDemo01 r2=new RunnableDemo01("http://pic.ruiwen.com/allimg/1708/598c8d37c8e9a56734.jpg?x-oss-process=style/qr.ruiwen","3.jpg");        RunnableDemo01 r3=new RunnableDemo01("https://gss1.bdstatic.com/-vo3dSag_xI4khGkpoWK1HF6hhy/baike/c0%3Dbaike150%2C5%2C5%2C150%2C50/sign=e90c38903ea85edfee81f671283d6246/3ac79f3df8dcd100ef9ca9e1788b4710b8122fe9.jpg","YIBO.jpg");​        new Thread(r1).start();        new Thread(r2).start();        new Thread(r3).start();​    }}class WebDownloader1{    public void downloader(String url,String name){        try {            FileUtils.copyURLToFile(new URL(url), new File(name));        }catch (IOException e){            e.printStackTrace();            System.out.println("IO异常,downloader方法出现异常");        }    }}

实现Runnable接口,能避免单继承局限性,灵活方便,方面同一个对象被多个线程使用

多个线程操作同一个资源的情况下,线程不安全,数据紊乱,并发

package com.wang.thread;//多个线程同时操作同一个对象//买火车票的例子​//多个线程操作同一个资源的情况下,线程不安全,数据紊乱public class RunnableDemo02 implements Runnable {    //票数    private int ticketNumbers=10;    @Override    public void run() {        while (true){            if (ticketNumbers<=0){                break;            }            try {                Thread.sleep(200);//模拟延时  延迟0.2秒            } catch (InterruptedException e) {                e.printStackTrace();            }            //Thread.currentThread().getName()当前执行线程的名字            System.out.println(Thread.currentThread().getName()+"拿到了第"+ticketNumbers--+"张票");        }    }​    public static void main(String[] args) {        RunnableDemo02 r=new RunnableDemo02();        new Thread(r,"小明").start();        new Thread(r,"老师").start();        new Thread(r,"王迎婧").start();    }}

案例:龟兔赛跑-Race

package com.practice.thread;​public class RaceDemo implements Runnable {     //胜利者    private static String winner;    @Override    public void run() {​        for (int i = 0; i <=100; i++) {            //模拟兔子休息            if (Thread.currentThread().getName().equals("兔子")&&i/10==0){                try {                    Thread.sleep(1);                } catch (InterruptedException e) {                    e.printStackTrace();                }            }            //判断比赛是否结束            Boolean flag=gameOver(i);            //如果比赛结束,就停止程序            if(flag){                break;            }            System.out.println(Thread.currentThread().getName()+"--->跑了"+i+"步");        }    }    //判断是否完成比赛    public boolean gameOver(int steps){        //判断是否有胜利者        if (winner!=null){//已经存在胜利者            return true;        }{            if (steps>=100){                winner=Thread.currentThread().getName();                System.out.println("winner is "+winner);                return true;            }        }        return false;    }​    public static void main(String[] args) {        RaceDemo raceDemo=new RaceDemo();//赛道只有一条​        new Thread(raceDemo,"兔子").start();        new Thread(raceDemo,"乌龟").start();​    }}

实现Callable接口

1、实现Callable接口,需要返回值类型

2、重写call方法,需要抛出异常

3、创建目标对象

4、创建执行服务:ExecutorService ser=Executors.newFixedThreadPool(1);

5、提交执行:Future<Boolean> result1=ser.submit(t1);

6、获取结果:boolean r1=result1.get();

7、关闭服务:ser.shutdownNow();

Callable的好处:可以定义返回值;可以抛出异常

package com.practice.thread;​import com.wang.duixiang.B;import org.apache.commons.io.FileUtils;​import java.io.File;import java.io.IOException;import java.net.URL;import java.util.concurrent.*;​/** * 线程创建方式三:实现Callable接口 * 1、实现Callable接口,需要返回值类型 * 2、重写call方法,需要抛出异常 * 3、创建目标对象 * 4、创建执行服务:ExecutorService ser=Executors.newFixedThreadPool(1); * 5、提交执行:Future <Boolean> result1=ser.submit(t1); * 6、获取结果:boolean r1=result1.get(); * 7、关闭服务:ser.shutdownNow(); */​public class CallableDemo01 implements Callable<Boolean> {    private String url;    private String name;    public CallableDemo01(String url,String name){        this.url=url;        this.name=name;    }    @Override    public Boolean call() {        WebDownloader2 downloader=new WebDownloader2();        downloader.downloader(url,name);        System.out.println("下载了文件名为:"+name);        return true;    }​    public static void main(String[] args) throws ExecutionException, InterruptedException {        CallableDemo01 c1=new CallableDemo01("http://pic.ruiwen.com/allimg/1708/598c8d3752d8939511.jpg?x-oss-process=style/qr.ruiwen","2.jpg");        CallableDemo01 c2=new CallableDemo01("http://pic.ruiwen.com/allimg/1708/598c8d37c8e9a56734.jpg?x-oss-process=style/qr.ruiwen","3.jpg");        CallableDemo01 c3=new CallableDemo01("https://gss1.bdstatic.com/-vo3dSag_xI4khGkpoWK1HF6hhy/baike/c0%3Dbaike150%2C5%2C5%2C150%2C50/sign=e90c38903ea85edfee81f671283d6246/3ac79f3df8dcd100ef9ca9e1788b4710b8122fe9.jpg","YIBO.jpg");       //创建执行服务:ExecutorService ser=Executors.newFixedThreadPool(1);        ExecutorService ser= Executors.newFixedThreadPool(3);       //提交执行:Future <Boolean> result1=ser.submit(t1);        Future<Boolean> result1=ser.submit(c1);        Future<Boolean> result2=ser.submit(c2);        Future<Boolean> result3=ser.submit(c3);        //获取结果:boolean r1=result1.get();        boolean r1=result1.get();        boolean r2=result2.get();        boolean r3=result3.get();        //关闭服务        ser.shutdownNow();    }}class WebDownloader2{    public void downloader(String url,String name){        try {            FileUtils.copyURLToFile(new URL(url), new File(name));        }catch (IOException e){            e.printStackTrace();            System.out.println("IO异常,downloader方法出现异常");        }    }
package com.wang.thread;import java.util.concurrent.*;//回顾总结线程的创建public class TestThread {    public static void main(String[] args) throws ExecutionException, InterruptedException {        new MyThread1().start();        new Thread(new MyThread2()).start();        MyThread3 myThread3=new MyThread3();        ExecutorService service= Executors.newFixedThreadPool(1);        Future<Integer> result=service.submit(myThread3);        Integer integer=result.get();        System.out.println(integer);        service.shutdownNow();    }}//1、继承Thread类class MyThread1 extends Thread{    @Override    public void run() {        System.out.println("MyThread1");    }}//2、实现Runnable接口class MyThread2 implements Runnable{    @Override    public void run() {        System.out.println("MyThread2");    }}//3、实现Callable接口class MyThread3 implements Callable<Integer>{    @Override    public Integer call() throws Exception {        System.out.println("MyThread3");        return 100;    }}
 
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!