本文共 9577 字,大约阅读时间需要 31 分钟。
进程是具有一定独立功能的的程序,进程是系统进行资源分配和调度的一个独立单元。
线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位.线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),但是它可与同属一个进程的其他的线程共享进程所拥有的全部资源
继承Thread类(重点)
实现Runnable接口(重点) 实现Callable接口第一步:自定义线程类继承Thread类。
第二步:重写run()方法,编写线程执行体。 第三步:创建线程对象,调用start()方法启动线程。package com.tjrac.demo01;//第一步:自定义线程类继承Thread类。//第二步:重写run()方法,编写线程执行体。//第三步:创建线程对象,调用start()方法启动线程。方法启动线程public class TestThread1 extends Thread{ @Override public void run() { for(int i=0;i<20;i++){ System.out.println("我在看代码"); } } public static void main(String[] args) { //创建线程对象 TestThread1 testThread1=new TestThread1(); //调用对象的start方法 testThread1.start(); for(int i=0;i<200;i++){ System.out.println("我学习多线程"+i); } }}
实战下载图片
package com.tjrac.demo01;import org.apache.commons.io.FileUtils;import java.io.File;import java.io.IOException;import java.net.URL;//第一步:自定义线程类继承Thread类。//第二步:重写run()方法,编写线程执行体。//第三步:创建线程对象,调用start()方法启动线程。方法启动线程public class TestThread1 extends Thread{ private String url;//网络图片的地址 private String name;//保存的文件名 public TestThread1(String url,String name){ this.url=url; this.name=name; } //下载线程的执行体 @Override public void run() { WedDownlaoder wedDownlaoder= new WedDownlaoder(); wedDownlaoder.Downlaoder(url,name); System.out.println(name+"下载完成"); } public static void main(String[] args) { //创建线程对象 TestThread1 t1=new TestThread1("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1577168219347&di=5bb4508ef618b0da3aed3d042eb8997e&imgtype=0&src=http%3A%2F%2Fimaegs.creditsailing.com%2Farticle%2F121%2F57_ua3ao__.jpg","陈声铭用多线程下载的图片01.jpg"); TestThread1 t2=new TestThread1("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1577168219347&di=5bb4508ef618b0da3aed3d042eb8997e&imgtype=0&src=http%3A%2F%2Fimaegs.creditsailing.com%2Farticle%2F121%2F57_ua3ao__.jpg","陈声铭用多线程下载的图片02.jpg"); TestThread1 t3=new TestThread1("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1577168219347&di=5bb4508ef618b0da3aed3d042eb8997e&imgtype=0&src=http%3A%2F%2Fimaegs.creditsailing.com%2Farticle%2F121%2F57_ua3ao__.jpg","陈声铭用多线程下载的图片03.jpg"); //调用对象的start方法 t1.start(); t2.start(); t3.start(); }}//下载器class WedDownlaoder{ //下载方法 public void Downlaoder(String url,String name){ try { FileUtils.copyURLToFile(new URL(url),new File(name)); } catch (IOException e) { e.printStackTrace(); System.out.println("Downlaoder方法异常"); } }}
总结:线程开启不一定执行,由CPU调度执行,不推荐用Thread类,因为要不免单继承的局限性。
第一步:实现Runnable接口。
第二步:重写run()方法。 第三步:将线程执行的接口放入接口实现类。package com.tjrac.demo01;//第一步:实现Runnable接口。//第二步:重写run()方法。//第三步:将线程执行的接口放入接口实现类。public class TestRunnable01 implements Runnable{ @Override public void run() { for(int i=0;i<20;i++){ System.out.println("下载完成"); } } public static void main(String[] args) { //创建Runnable接口的实现类对象 TestRunnable01 testRunnable = new TestRunnable01(); //创建线程对象,通过线程对象来启动线程 new Thread(testRunnable).start(); for(int i=0;i<500;i++){ System.out.println("下载完成"+i); } }}
实战下载图片(荣耀战魂)
package com.tjrac.demo01;import org.apache.commons.io.FileUtils;import java.io.File;import java.io.IOException;import java.net.URL;public class TestRunnable02 implements Runnable{ private String url;//网络图片的地址 private String name;//保存的文件名 public TestRunnable02(String url,String name){ this.url=url; this.name=name; } //下载线程的执行体 @Override public void run() { RunnableDownlaoder runnableDownlaoder= new RunnableDownlaoder(); runnableDownlaoder.Downlaoder(url,name); System.out.println(name+"下载完成"); } public static void main(String[] args) { //创建线程对象 TestRunnable02 t1=new TestRunnable02("https://imgsa.baidu.com/forum/pic/item/8a13632762d0f703b83556ae07fa513d2697c539.jpg","陈声铭用多线程下载的图片04.jpg"); //调用对象的start方法 new Thread(t1).start(); }}//下载器class RunnableDownlaoder{ //下载方法 public void Downlaoder(String url,String name){ try { FileUtils.copyURLToFile(new URL(url),new File(name)); } catch (IOException e) { e.printStackTrace(); System.out.println("Downlaoder方法异常"); } }}
总结:推挤使用Runnable接口,方便灵活,可以一个对象被多个线程使用,但是会出现多线程并发的问题。
多个线程同时操作一个对象实战 卖火车票package com.tjrac.demo01;//多个线程同时操作一个对象//卖火车票public class TestRunnable03 implements Runnable { private int ticket=10; @Override public void run() { //模拟延时 try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); } while (true) { if(ticket<=0){ break; } System.out.println(Thread.currentThread().getName()+"买到了第"+ticket--+"票"); } } public static void main(String[] args) { TestRunnable03 testRunnable03=new TestRunnable03(); new Thread(testRunnable03,"陈声铭").start(); new Thread(testRunnable03,"雷志明").start(); new Thread(testRunnable03,"唐可明").start(); new Thread(testRunnable03,"陈笑").start(); }}
package com.tjrac.demo01;import org.apache.commons.io.FileUtils;import java.io.File;import java.io.IOException;import java.net.URL;import java.util.concurrent.*;public class TestCallable01 implements Callable{ private String url;//网络图片的地址 private String name;//保存的文件名 public TestCallable01(String url,String name){ this.url=url; this.name=name; } //下载线程的执行体 @Override public Boolean call() { RunnableDownlaoder runnableDownlaoder= new RunnableDownlaoder(); runnableDownlaoder.Downlaoder(url,name); System.out.println(name+"下载完成"); return true; } public static void main(String[] args) throws ExecutionException, InterruptedException { //创建线程对象 TestCallable01 t1=new TestCallable01("https://imgsa.baidu.com/forum/w%3D580%3B/sign=16a0044f35f33a879e6d0012f6671138/37d12f2eb9389b508c5b672d8a35e5dde7116e2d.jpg","陈声铭用多线程下载的图片05.jpg"); //创建执行服务 ExecutorService ser = Executors.newFixedThreadPool(1); //提交执行 Future r1=ser.submit(t1); //获取结果 boolean rs1=r1.get(); //关闭服务器 ser.shutdownNow(); }}//下载器class CallableDownlaoder{ //下载方法 public void Downlaoder(String url,String name){ try { FileUtils.copyURLToFile(new URL(url),new File(name)); } catch (IOException e) { e.printStackTrace(); System.out.println("Downlaoder方法异常"); } }}
线程的5个状态
package com.kuang.springbootmybatis.controller;public class TestRunnable03 implements Runnable { public boolean flag=true; @Override public void run() { int ticket=0; while (flag) { System.out.println("Thread...run"+ticket++); } } public void stop(){ this.flag=false; } public static void main(String[] args) { TestRunnable03 testRunnable03=new TestRunnable03(); new Thread(testRunnable03).start(); for (int i=0;i<=10000;i++){ System.out.println("main"+i); if(i==9000){ testRunnable03.stop(); System.out.println("线程停止"); } } }}
package com.kuang;import jdk.internal.dynalink.beans.StaticClass;import java.text.SimpleDateFormat;import java.util.Date;public class TestSleep { public static void main(String[] args){ Date data=new Date(System.currentTimeMillis()); while(true){ try { Thread.sleep(1000); System.out.println(new SimpleDateFormat("HH:mm:ss").format(data)); data=new Date(System.currentTimeMillis()); } catch (InterruptedException e) { e.printStackTrace(); } } } //倒计时 public static void tenDown() throws InterruptedException { int num=10; while(true){ Thread.sleep(1000); System.out.println(num--);; if(num<=0){ break; } } }}
package com.kuang;public class TestYield { public static void main(String[] args){ MyYield myYield=new MyYield(); new Thread(myYield,"a").start(); new Thread(myYield,"b").start(); }}//礼让class MyYield implements Runnable{ @Override public void run() { System.out.println(Thread.currentThread().getName()+"线程开始"); Thread.yield(); System.out.println(Thread.currentThread().getName()+"线程结束"); }}
转载地址:http://ilrwi.baihongyu.com/