• 线程创建


    线程创建

    三种创建方式:①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接口的实现类,调用start
    public 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;
    }
    }
     
  • 相关阅读:
    张季跃 201771010139《面向对象程序设计(java)》第三周学习总结
    实验十二
    201771010142 张燕& 杨蓉庆 实验十一 集合
    实验十 泛型程序设计技术
    第九次实验
    第八次实验
    进度条
    实验七 继承附加实验
    第六次实验
    实验四
  • 原文地址:https://www.cnblogs.com/wyj96/p/11979701.html
Copyright © 2020-2023  润新知