概述线程、线程创建

多线程详解

1.1 概述 线程介绍

  • 多任务

吃饭玩手机,开车打点滴,蹲坑打游戏

现实中太多这样同时做多件事情的例子了,看起来是多个任务都在做,其实本质上我们的大脑在同一时间依旧只做了一件事情。

  • 多线程

    道路窄,拓宽,多条路

    收银,多个收银员

  • 程序 进程(process) 线程(thread)

    • 说起进程,就不得不说下程序。程序是指令和数据的有序集合,其本身没有任何运行的含义,是—个静态的概念。

    • 进程则是执行程序的一次执行过程,它是一个动态的概念。 是系统资源分配的单位

    • 通常在一个进程中可以包含若干个线程,当然一个进程中至少有一个线程,不然没有存在的意义。线程是CPU调度和执行的的单位。

◆线程就是独立的执行路径;

◆在程序运行时,即使没有自己创建线程,后台也会有多个线程,如主线程,gc线程(垃圾回收); main()称之为主线程,为系统的入口,用于执行整个程序;

◆在一个进程中,如果开辟了多个线程,线程的运行由调度器安排调度,调度器是与操作系统紧密相关的,先后顺序是不能人为的干预的。

◆对同一份资源操作时,会存在资源抢夺的问题,需要加入并发控制;

◆线程会带来额外的开销,如cpu调度时间,并发控制开销。

◆每个线程在自己的工作内存交互,内存控制不当会造成数据不一致

 

 

1.2 线程创建

三种创建方式

概述线程、线程创建

概述线程、线程创建

 

Thread:

package com.zishi.lensson1;
?
//创建线程方式一:继承Thread类,重写run()方法,调用start开启线程
public class TestThread1 extends Thread{
?
   @Override
   public void run() {
       //run方法线程体
       for (int i = 0; i < 20; i++) {
           System.out.println("我在摸鱼-----"+i);
      }
  }
?
   public static void main(String[] args) {
?
       //mian线程,主线程
       //创建一个线程对象
       TestThread1 testThread1 = new TestThread1();
?
       //调用start()方法开启线程
       testThread1.start();
       
?
       for (int i = 0; i < 1000; i++) {
           System.out.println("我在学习多线程"+i);
      }
?
  }
}

概述线程、线程创建

start()方法 同时进行

testThread1.run();

概述线程、线程创建

先执行run()线程

网图下载

package com.zishi.lensson1;
?
import org.apache.commons.io.FileUtils;
?
import java.io.File;
import java.io.IOException;
import java.net.URL;
?
//练习Thread,实现多线程同步下载图片
public class TestThread2 extends Thread{
?
   private String url;//网络图片地址
   private String name;//保存的文件名
?
   public TestThread2(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) {
       TestThread2 t1 = new TestThread2("https://pic1.zhimg.com/v2-56e7df4fe56e37c2c4d2478d946cd9b8_b.jpg", "1.jpg");
       TestThread2 t2 = new TestThread2("https://pic2.zhimg.com/v2-d7be668fc1616710f55070f4c7cbd081_b.jpg", "2.jpg");
       TestThread2 t3 = new TestThread2("https://pic3.zhimg.com/v2-e193c36c5e2809399ccc1cc0e15b1d52_b.jpg", "3.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));
      } catch (IOException e) {
           e.printStackTrace();
           System.out.println("IO异常,downloader方法出错");
      }
  }
}

Runnable:

package com.zishi.lensson1;
?
//创建线程方式2: 实现Runnable接口,重写run方法,
//执行线程需要丢入runnable接口实现类,调用start方法
public class TestThread3 implements Runnable{
   @Override
   public void run() {
       //run方法线程体
       for (int i = 0; i < 200; i++) {
           System.out.println("我在摸鱼------"+i);
      }
  }
?
   public static void main(String[] args) {
       //创建runnable接口实现类对象
       TestThread3 testThread3 = new TestThread3();
?
       //创建线程对象,通过线程对象来开启我们的线程,代理
//       Thread thread = new Thread(testThread3);
//       thread.start();
?
       new Thread(testThread3).start();
?
       for (int i = 0; i < 1000; i++) {
           System.out.println("我在学习多线程---"+i);
      }
  }
}

 

start() 同步进行

概述线程、线程创建

概述线程、线程创建

Thread 实现了 Runnale

//创建线程对象,通过线程对象来开启我们的线程,代理
//       Thread thread = new Thread(testThread3);
//       thread.start();

概述线程、线程创建

推荐使用Runnable接口

同一个对象被多线程使用 例子:

package com.zishi.lensson1;
?
//多线程同时操作同一个对象
//买火车票的例子
public class TestThread4 implements Runnable{
?
   //票数
   private int ticketNums = 10;
?

   @Override
   public void run() {
       while (true){
           if (ticketNums<=0){
               break;
          }
//模拟延时
           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();
  }
}

案例:龟兔赛跑

package com.zishi.lensson1;
?
//模拟龟兔赛跑
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(1);
              } 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;
      }{
           if (steps>=100){
               winner = Thread.currentThread().getName();
               System.out.println("winner is "+winner);
               return true;
          }
      }
       return false;
  }
?
   public static void main(String[] args) {
       Race race = new Race();
?
       new Thread(race,"兔子").start();
       new Thread(race,"乌龟").start();
  }
}

 

概述线程、线程创建

上一篇:unity StreamingAssets文件夹作用


下一篇:Java运行时类型信息RTTI