线程创建

线程创建

三种创建方式:①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;
}
}
 
posted @ 2019-12-03 21:47  王迎婧  阅读(357)  评论(0编辑  收藏  举报