Java线程学习笔记之实现多线程的方法

继承Thread
package com.bin.thread;

public class ThreadTest01 extends Thread {
    @Override
    public void run() {
        for (int i = 0; i <100; i++){
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("我在执行run方法--"+i);
        }
    }

    public static void main(String[] args) throws InterruptedException {
        ThreadTest01 test01 = new ThreadTest01();
        test01.start();
        for (int i = 0; i <100; i++){
            Thread.sleep(100);
            System.out.println("我在执行main方法--"+i);
        }
    }
}

代码执行效果:
在这里插入图片描述

子类继承Thread类具备多线程能力
启动线程:子类对象.strat();
不建议使用:避免面向对象单继承的局限性。

实现Runable
package com.bin.thread;

/**
 *
 */
public class ThreadTest03 implements Runnable {
    public void run() {
        for (int i = 0; i <100; i++){
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("我在执行run方法--"+i);
        }
    }

    public static void main(String[] args) throws InterruptedException {
        ThreadTest03 threadTest03 = new ThreadTest03();
        new Thread(threadTest03).start();
        for (int i = 0; i <100; i++){
            Thread.sleep(100);
            System.out.println("我在执行main方法--"+i);
        }
    }
}

执行效果:
在这里插入图片描述
通过实现Runable接口具备多线程能力
启动线程:new Thread(实现类实例).start();
推荐使用:避免单继承的局限性,灵活方便,方便同一对象被多个线程使用。

小练习:启动多线程下载图片

导入jar包

<dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.6</version>
        </dependency>

实现功能:

package com.bin.thread;

import org.apache.commons.io.FileUtils;

import java.io.File;
import java.io.IOException;
import java.net.URL;

public class ThreadTest02 extends Thread {
    private String url;
    private String name;

    public ThreadTest02(String url, String name) {
        this.url = url;
        this.name = name;
    }

    @Override
    public void run() {
        WebDownload download = new WebDownload();
        download.downloadPicture(url,name);
        System.out.println("下载了"+name+"图片");
    }

    public static void main(String[] args) {
        ThreadTest02 threadTest1 = new ThreadTest02("https://picsum.photos/536/354", "1.jpg");
        ThreadTest02 threadTest2 = new ThreadTest02("https://picsum.photos/seed/picsum/536/354", "2.jpg");
        ThreadTest02 threadTest3 = new ThreadTest02("https://picsum.photos/id/1084/536/354?grayscale", "3.jpg");
         threadTest1.start();
         threadTest2.start();
         threadTest3.start();
    }
}

class WebDownload {
    public void downloadPicture(String url ,String name){
        try {
            FileUtils.copyURLToFile(new URL(url),new File(name));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

执行效果:
在这里插入图片描述
在这里插入图片描述
通过控制台的输出结果,可以观察到图片下载并不是顺序执行的,而是cpu通过线程调度执行。

通过实现Callable接口实现图片下载
package com.bin.callable;



import com.bin.thread.ThreadTest02;
import com.bin.thread.WebDownload;

import java.util.concurrent.*;

public class CallableTest01 implements Callable<Boolean> {
    private String url;
    private String name;

    public CallableTest01(String url,String name) {
        this.url = url;
        this.name = name;
    }

    public Boolean call() throws Exception {
        WebDownload download = new WebDownload();
        download.downloadPicture(url,name);
        System.out.println("下载了图片"+name);
        return true;
    }

    public static void main(String[] args) {
        CallableTest01 c1 = new CallableTest01("https://picsum.photos/536/354", "1.jpg");
        CallableTest01 c2 = new CallableTest01("https://picsum.photos/seed/picsum/536/354", "2.jpg");
        CallableTest01 c3 = new CallableTest01("https://picsum.photos/id/1084/536/354?grayscale", "3.jpg");

        //创建线程池
        ExecutorService executorService = Executors.newFixedThreadPool(3);

        //提交执行
        Future<Boolean> submit1 = executorService.submit(c1);
        Future<Boolean> submit2 = executorService.submit(c2);
        Future<Boolean> submit3 = executorService.submit(c3);

        //获取结果

        try {
            Boolean b1 = submit1.get();
            Boolean b2 = submit2.get();
            Boolean b3 = submit3.get();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }

        //关闭线程池
        executorService.shutdownNow();

    }


}

执行效果:

在这里插入图片描述

小测试

测试多个线程操作同一对象会不会出现线程安全问题。

package com.bin.thread;

public class ThreadTest04 implements Runnable {
    private Integer ticketNums = 10;
    public void run() {
        while (true){
            if (ticketNums<=0){
                break;
            }
            System.out.println(Thread.currentThread().getName()+"抢到了第"+ticketNums+"张票");
            ticketNums--;
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        ThreadTest04 threadTest04 = new ThreadTest04();
        //多个线程操作同一对象
        new Thread(threadTest04,"腾讯主席").start();
        new Thread(threadTest04,"阿里主席").start();
        new Thread(threadTest04,"网易主席").start();
        new Thread(threadTest04,"扫地的我").start();
    }
}

执行结果:
在这里插入图片描述
结果很明显。

注:本次学习于狂神老师的b站视频。网址:https://www.bilibili.com/video/BV1V4411p7EF

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值