天天看点

程序,进程,线程;继承Thread类;用多线程下载图片;实现Runnable接口;多线程龟兔赛跑;callable下载图片(了解)

程序.进程(Process).线程(Thread)

在操作系统中运行的程序就是进程,程序是代码,是死的,是一个静态的概念,而进程是执行程序的一次执行过程,是一个动态的概念,是系统资源分配的单位,比如QQ,LOL,IDE等等。。

一个进程可以有多个线程,如在看视频时,可以同时听声音,看图像,看弹幕,等等。

即使一个进程什么都不干,里面也有一个main线程(主线程) ,线程就是独立的执行路径。

注意:很多多线程是模拟出来的,真正的多线程是只有多个CPU,即多核,如 服务器。而模拟出来的多线程在一个CPU下,同一时间只执行一个代码,只是切换的很快而已。

创建线程之一:

继承Thread (不建议使用,避免OOP单继承局限性)

  1. 自定义线程类继承Thread类
  2. 重写run()方法,编写线程执行体
  3. 创建线程对象,调用start()方法启动线程

实例如下:

public class TestThread1 extends Thread {
    @Override
    public void run() {
        super.run();
        //run方法线程体
        for (int i = 0; i < 20; i++) {
            System.out.println("run线程。。。。");
        }
    }
    
    public static void main(String[] args) {
        //main线程,主线程
        //创建线程对象,调用start方法开启线程
        TestThread1 testThread1 = new TestThread1();
        testThread1.start();
        for (int i = 0; i < 200; i++) {
            System.out.println("main......");
        }
    }
}
           
程序,进程,线程;继承Thread类;用多线程下载图片;实现Runnable接口;多线程龟兔赛跑;callable下载图片(了解)

注意:线程开启不一定立即执行,由cpu调度执行。调用多个线程对象的start()方法,执行顺序是不一定的。

用多线程下载图片

下载一个commons IO包,他是别人针对开发IO流功能的工具类库,直接百度搜索即可,将其拷到项目里的一个新建文件夹里,此时他不能直接用,要右键此文件夹选中Add as Library添加到库里面。此时如果查看项目资源目录,里面就有一个libraries。

1.先写一个下载器,里面有一个下载方法,它是通过FileUtils这个工具类的copyURLToFile方法将图片下载下来。

//下载器,因为这个定义的类全都放在了一个页面所以没有public,一个java类中只能有一个public class类
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异常,dowmloader方法出现问题");
       }
    }
}
           

2.要实现一个线程类,然后写一个有参构造,用来丢入地址和名字,再然后重写run()方法,它是下载图片线程的执行体。最后在main()函数中通过三个构造器创建三个线程,然后用三个start()方法把这三个线程同时启动起来。

public class TextThread2 extends Thread{
    private String url;//网络图片地址
    private String name;//保存的文件名

    public TextThread2(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) {
        TextThread2 t1=new TextThread2("此处写要下载图片的地址","给想要下载的图片命名");
        TextThread2 t2=new TextThread2("此处写要下载图片的地址","给想要下载的图片命名");
        TextThread2 t3=new TextThread2("此处写要下载图片的地址","给想要下载的图片命名");
        t1.start();
        t2.start();
        t3.start();
    }
}
           

创建线程方法二:

实现Runnable(推荐该方式)可避免单继承局限性,灵活,方便同一个对象被多个线程使用

  1. 定义MyRunnable类实现Runnable接口
  2. 重写run()方法,编写线程执行体
  3. 创建线程对象,调用start()方法启动线程

实例如下:

和继承Thread类那种方法差不多,这就是将Runable接口的实现类对象丢入Thread里面,调用start()启动.

public class TextThread3 implements Runnable {
    @Override
    public void run() {
        //run()方法线程体
        for (int i = 0; i < 200; i++) {
            System.out.println("run"+i);
        }
    }

    public static void main(String[] args) {
        //创建runnable接口的实现类对象
        TextThread3 textThread3 = new TextThread3();
        //创建线程对象,通过线程对象来开启我们的线程,代理
        Thread thread = new Thread(textThread3);
        thread.start();
        //这两句等价于 new Thread(testThread3).start();

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

用runnable多线程下载图片

和第一种方式比较只需改动两处——画“***************************”处

public class TextThread2 implements Runnable{              ***************************************
    private String url;//网络图片地址
    private String name;//保存的文件名

    public TextThread2(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) {
        TextThread2 t1=new TextThread2("此处写要下载图片的地址","给想要下载的图片命名");
        TextThread2 t2=new TextThread2("此处写要下载图片的地址","给想要下载的图片命名");
        TextThread2 t3=new TextThread2("此处写要下载图片的地址","给想要下载的图片命名");
        new Thread(t1).start();                          **************************************
        new Thread(t2).start();                          **************************************
        new Thread(t3).start();                          **************************************
    }
}
//下载器
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异常,dowmloader方法出现问题");
       }
    }
}
           

一个对象被多个线程使用的实例:

//多个线程同时操作一个Runnable接口的对象
//买火车票的例子
public class TestThread4 implements Runnable{

    //票数
    private int ticketNums = 10;

    @Override
    public void run() {
        while(true){
            if(ticketNums<=0){
                break;
            }
            //模拟延时,200毫秒,0.2秒
            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()+"拿到了"+ticketNums--+"票");
        }
    }


    public static void main(String[] args) {
        //一个资源
        TestThread4 testThread4 = new TestThread4();
        //多个代理
        new Thread(testThread4,"小红").start();
        new Thread(testThread4,"小白").start();
        new Thread(testThread4,"小黑").start();
    }
}
           

多线程龟兔赛跑

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("兔子")&&i%10==0) {
                try {
                    Thread.sleep(3);
                } 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) {
                //Thread.currentThread()这是Theard类的currentThread()方法,意思就是”当前线程“
                winner = Thread.currentThread().getName();
                System.out.println("winner is" + winner);
                return true; }
        else {
            return false;
        }
    }


    public static void main(String[] args) {
        Race race = new Race();
        //由于两个线程公用一个资源,都用run方法,谁先跑完执行方法里面的break,另一个也就跑不了了
        new Thread(race,"兔子").start();
        new Thread(race,"乌龟").start();

    }
}
           

Callable下载图片(了解)

程序,进程,线程;继承Thread类;用多线程下载图片;实现Runnable接口;多线程龟兔赛跑;callable下载图片(了解)
程序,进程,线程;继承Thread类;用多线程下载图片;实现Runnable接口;多线程龟兔赛跑;callable下载图片(了解)

继续阅读