首页 > 编程语言 > 详细

多线程的实现方式

时间:2021-05-08 16:29:22      阅读:18      评论:0      收藏:0      [点我收藏+]

1.多线程

1.1线程的创建方式

1)继承Thread类

//创建线程方式1:继承Thread类,重写run()方法,
// 调用start开启线程:子类对象.start()
//线程开启不一定立即执行,由CPU调度执行
public class TestThread extends Thread {
    public void run() {
        //run()方法线程体
        for (int i = 0; i < 20; i++) {
            System.out.println("第" + i + "个");
        }
    }

    public static void main(String[] args) {
        //main线程,主线程

        //创建一个线程对象,调用start()方法开启线程。
        TestThread testThread1 = new TestThread();
        testThread1.start();

        for (int i = 0; i < 2000; i++) {
            System.out.println("learning" + i);
        }
    }
}

技术分享图片

实验结果可以看出来,两个线程交替执行

2)实现Runnable接口

package miar;

//创建线程方式2:实现runnable方法,重写run方法,
// 执行线程需要丢入runnable接口实现类,调用start()
//传入目标对象+Thread对象.start()
//推荐使用:避免单继承局限性,灵活方便,方便同一个对象被多个线程使用
public class TestThread3 implements Runnable {
    @Override
    public void run() {
        for (int i = 0; i < 200; i++) {
            System.out.println("playing"+i);
        }
    }

    public static void main(String[] args) {
        //创建runnable接口的实现对象
        TestThread3 testThread3 = new TestThread3();
        //创建线程对象,通过线程对象来开启线程,代理
        Thread thread = new Thread(testThread3);

        thread.start();

        for (int i = 0; i < 1000; i++) {
            System.out.println("learning" + i);
        }
    
    }
}

技术分享图片

2).1 通过实现Runnable接口进行线程的多继承(并行)

//多个线程操作同一个对象
//买火车票的例子

//发现问题,多个线程操作同一个资源的情况下,线程不安全。数据紊乱
public class TestThread4 implements Runnable{
    //票数
    int ticketNums = 10;
    @Override
    public void run() {
        while(true){
            if (ticketNums<=0)
                break;
//            //模拟延时
//            try {
//                Thread.sleep(200);
//            } catch (InterruptedException e) {
//                e.printStackTrace();
//            }
            System.out.println(Thread.currentThread().getName()+"--->拿到了第"+ticketNums--+"张票");
        }
    }

    public static void main(String[] args) {
        TestThread4 ticket = new TestThread4();
        new Thread(ticket,"小明").start();
        new Thread(ticket,"小红").start();
        new Thread(ticket,"小兰").start();
    }
}

技术分享图片

2).2 龟兔赛跑案例

//模拟龟兔赛跑
public class Race implements Runnable{
    //胜利者
    private static String winner;
    @Override
    public void run() {
        for (int i = 0; i <= 100; i++) {
            if (Thread.currentThread().getName().equals("rabbit") && (i%10==0)){
                try {
                    Thread.sleep(5);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

            boolean flag = gameOver(i);
            if (flag)
                break;
            System.out.println(Thread.currentThread().getName()+"--->跑了"+i+"步");
        }
    }

    private boolean gameOver(int steps){
        //判断是否有胜利者
        if (winner!=null)
            return true;
        else {
            if (steps==100){
                winner = Thread.currentThread().getName();
                System.out.println("winner is "+winner);
                return true;
            }
        }
        return false;
    }

    public static void main(String[] args) {
        Race race = new Race();
        new Thread(race,"rabbit").start();
        new Thread(race,"turtle").start();
    }
}

技术分享图片

技术分享图片

3)实现Callable接口

3).1实现方式

实现callable接口,实现call( )函数,有返回值

1.创建一个服务

2.提交线程到服务

3.执行

4.结束服务

public class TestCallable implements Callable<Boolean> {

    private String url;   //网络图片地址
    private String name;  //保存的文件名

    public TestCallable(String url, String name) {
        this.url = url;
        this.name = name;
    }
    //下载图片的线程执行体
    @Override
    public Boolean call() {
        WebDownloader webDownloader = new WebDownloader();
        webDownloader.downloader(url,name);
        System.out.println("下载了文件名为:"+name);
        return true;
    }

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        TestCallable t1 = new TestCallable("https://pics5.baidu.com/feed/d058ccbf6c81800ac8ba09de5b1808fc838b47b3.jpeg?token=5185e26d4a936f2b1b38e3321aa64262&s=E29315C71331BBD054F1DC870300A0C3","1.png");
        TestCallable t2 = new TestCallable("https://gimg2.baidu.com/image_search/src=http%3A%2F%2Finews.gtimg.com%2Fnewsapp_bt%2F0%2F9996658365%2F1000.jpg&refer=http%3A%2F%2Finews.gtimg.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1623040765&t=e5eb506465fdaba9c1dd543b0b30c80c","2.png");
        TestCallable t3 = new TestCallable("https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fn.sinaimg.cn%2Fsinacn20190816s%2F736%2Fw436h300%2F20190816%2Fc71c-ichcymv7322423.jpg&refer=http%3A%2F%2Fn.sinaimg.cn&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1623040870&t=a5f3021037d1221b163237979482bbac","3.png");
        //创建执行服务
        ExecutorService ser = Executors.newFixedThreadPool(3);
        //提交执行
        Future<Boolean> r1 = ser.submit(t1);
        Future<Boolean> r2 = ser.submit(t2);
        Future<Boolean> r3 = ser.submit(t3);
        //获取结果
        boolean rs1 = r1.get();
        boolean rs2 = r2.get();
        boolean rs3 = r3.get();
        //关闭服务
        ser.shutdown();
    }
}

//下载器
class WebDownloader {
    //下载方法
    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接口。

多线程的实现方式

原文:https://www.cnblogs.com/miarlee/p/14744951.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!