java基础(3)——多线程(1)线程实现

多线程

线程简介

程序:指令和数据的有序集合,其本身没有任何含义,是一个静态概念

进程:执行程序的一次执行过程,动态概念,是系统资源分配的基本单位

线程:通常一个进程可以包含若干个线程,线程是cpu调度和执行的单位

线程实现 (重点)

在这里插入图片描述

继承Thread类 (重点)
  1. 继承Thread类
  2. 重写run()
  3. 用start()调用
public class Main extends Thread{
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println("run()" + i);
        }
    }
    public static void main(String[] args) {
        Main main = new Main();
        main.start();//开启子线程,此时会交替执行

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

例子:同时下载图片

public class TestThread extends Thread {
    private String url;
    private String fileName;
    public TestThread(String url, String fileName){
        this.url = url;
        this.fileName = fileName;
    }
    @Override
    public void run() {
        DownloadPic down = new DownloadPic();
        down.down(url, fileName);
        System.out.println(fileName + "下载成功");
    }

    public static void main(String[] args) {
        TestThread t1 = new TestThread("https://img.alicdn.com/tfs/TB1JHFR1.T1gK0jSZFrXXcNCXXa-320-560.jpg", "1.jpg");
        TestThread t2 = new TestThread("https://img.alicdn.com/tfs/TB1JHFR1.T1gK0jSZFrXXcNCXXa-320-560.jpg", "2.jpg");
        TestThread t3 = new TestThread("https://img.alicdn.com/tfs/TB1JHFR1.T1gK0jSZFrXXcNCXXa-320-560.jpg", "3.jpg");

        //下载顺序由cpu调度
        t1.start();
        t2.start();
        t3.start();
    }
}
class DownloadPic{//下载图片的类
    public void down(String url, String fileName){
        try {
            FileUtils.copyURLToFile(new URL(url), new File(fileName));//在common-io中
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("下载异常");
        }
    }
}
实现Runnable接口(重点)

建议用此方法,因为Java是单继承

  1. 实现Runnable接口
  2. 重写run()
  3. 用start()调用
public class TestRun implements Runnable {
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println("run()" + i);
        }
    }

    public static void main(String[] args) {
        TestRun tRun = new TestRun();//在创建Thread时作为参数传递
        new Thread(tRun).start();//开启子线程   

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

并发问题:会有不同的线程拿到同一张票

public class Bingfa implements Runnable {
    private int count = 10;
    @Override
    public void run() {
        while (true){
            if (count <= 0){
                break;
            }
            System.out.println(Thread.currentThread().getName() + "抢到了第" + count-- + "张票");
        }
    }

    public static void main(String[] args) {
        Bingfa bingfa = new Bingfa();
        new Thread(bingfa, "小明").start();
        new Thread(bingfa, "黄牛党").start();
        new Thread(bingfa, "老师").start();
    }
}

例子: 龟兔赛跑

public class Race implements Runnable {
    private static String winner;
    @Override
    public void run() {
        for (int i = 1; i <= 10; i++) {
            //让兔子休眠
            if (Thread.currentThread().getName().equals("兔子") && i % 2 == 0) {
                try {
                    Thread.sleep(5);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
                boolean win = getWin(i);
                if (win) {
                    break;
                }
                System.out.println(Thread.currentThread().getName() + "跑了第" + i + "步");
            }
        }

    public boolean getWin(int step) {
        boolean flag = false;
        if (winner != null) {//已经存在胜利者
            flag = true;
        }
        if (step == 10) {
            winner = Thread.currentThread().getName();
            System.out.println(Thread.currentThread().getName() + "is a winner!");
            flag = true;
        }
            return flag;
    }
    public static void main(String[] args) {
        Race race = new Race();
        new Thread(race, "兔子").start();
        new Thread(race, "乌龟").start();
    }
}
实现Callable接口(了解即可)
  1. 实现Callable接口,需要返回值类型
  2. 重写call(),需要抛出异常
  3. 创建目标对象
  4. 创建执行服务
  5. 提交执行
  6. 获取结果
  7. 关闭服务

例子:同时下载图片

public class TestCall implements Callable<Boolean> {//实现callable
    private String url;
    private String name;
    public TestCall(String url, String name){
        this.url = url;
        this.name = name;
    }
    @Override
    public Boolean call() throws Exception {//重写call()
        DownloadPict down = new DownloadPict();
        down.down(url, name);
        System.out.println(name + "下载成功");
        return true;
    }

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        //创建执行服务
        ExecutorService pool = Executors.newFixedThreadPool(3);
        //提交执行
        Future<Boolean> s1 = pool.submit(new TestCall("https://img.alicdn.com/tfs/TB1JHFR1.T1gK0jSZFrXXcNCXXa-320-560.jpg", "1.jpg"));
        Future<Boolean> s2 = pool.submit(new TestCall("https://img.alicdn.com/tfs/TB1JHFR1.T1gK0jSZFrXXcNCXXa-320-560.jpg", "2.jpg"));
        Future<Boolean> s3 = pool.submit(new TestCall("https://img.alicdn.com/tfs/TB1JHFR1.T1gK0jSZFrXXcNCXXa-320-560.jpg", "3.jpg"));
        //获取结果
        Boolean bs1 = s1.get();
        Boolean bs2 = s2.get();
        Boolean bs3 = s3.get();
        //关闭执行
        pool.shutdown();

        System.out.println(bs1);
        System.out.println(bs2);
        System.out.println(bs3);

    }
}
class DownloadPict{
    public void down(String url, String name){
        try {
            FileUtils.copyURLToFile(new URL(url), new File(name));//在common-io.jar中
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("下载异常");
        }
    }
}

如有不对的地方欢迎指出,共同进步!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值