e小白

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 84|回复: 0

线程(第一部分)

[复制链接]

4

主题

4

帖子

32

积分

新手上路

Rank: 1

积分
32
发表于 2021-6-23 20:17:49 | 显示全部楼层 |阅读模式
本帖最后由 yupic1 于 2021-6-23 20:34 编辑


三种创建方式

继承Thread类


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


不推荐:避免OOP单继承局限性
  1. public class test extends Thread {

  2.     @Override
  3.     public void run() {
  4.         //run()方法线程体
  5.         for (int i = 0; i<1000; i++){
  6.             System.out.println("我在看代码-----"+i);
  7.         }
  8.     }

  9.     public static void main(String[] args) {
  10.         //创建一个线程对象
  11.         test testThread = new test();
  12.         //调用start()方法开启线程
  13.         testThread.start();

  14.         for (int i = 0; i<1000; i++){
  15.             System.out.println("我在学习线程-----"+i);
  16.         }
  17.     }
  18. }
复制代码
做个图片下载器
  1. package demo01;

  2. import org.apache.commons.io.FileUtils;

  3. import java.io.File;
  4. import java.io.IOException;

  5. import java.net.URL;

  6. //练习Thread,实现多线程同步下载
  7. public class testThread02 extends Thread{

  8.     private String url;
  9.     private String name;

  10.     public testThread02 (String url, String name){
  11.         this.url = url;
  12.         this.name = name;
  13.     }

  14.     @Override
  15.     public void run() {
  16.         WebDownloader webDownloader = new WebDownloader();
  17.         webDownloader.downloader(url,name);
  18.         System.out.println("下载了文件名为"+name);
  19.     }

  20.     public static void main(String[] args) {
  21.         testThread02 t1 = new testThread02("https://wx1.sinaimg.cn/mw690/b4b0bcb1ly1glu9ssxgi7j22bc334e82.jpg","1.jpg");
  22.         testThread02 t2 = new testThread02("https://wx4.sinaimg.cn/mw690/b4b0bcb1ly1glu9subwvnj22bc334hdu.jpg","2.jpg");
  23.         testThread02 t3 = new testThread02("https://wx1.sinaimg.cn/mw690/b4b0bcb1ly1glu9svt367j22bc334hdu.jpg","3.jpg");

  24.         t1.start();
  25.         t2.start();
  26.         t3.start();

  27.     }
  28. }

  29. //下载器
  30. class WebDownloader{
  31.     //下载方法
  32.     public void downloader(String url, String name){
  33.         try {
  34.             FileUtils.copyURLToFile(new URL(url),new File(name));
  35.         } catch (IOException e) {
  36.             e.printStackTrace();
  37.             System.out.println("IO异常,downloader方法出现异常");
  38.         }
  39.     }
  40. }
复制代码
实现Runnable接口
自定义线程类实现Runnable接口,重写run()方法,编写线程执行体,创建实现类对象,创建Thread类对象,把实现类对象作为Thread构造函数的参数,调用Thread类对象的start()方法启动线程。

推荐:避免单继承局限性,灵活方便,方便同一个对象被多个线程使用。
  1.     public static void main(String[] args) {
  2.         testThread02 t1 = new testThread02("https://wx1.sinaimg.cn/mw690/b4b0bcb1ly1glu9ssxgi7j22bc334e82.jpg","1.jpg");
  3.         testThread02 t2 = new testThread02("https://wx4.sinaimg.cn/mw690/b4b0bcb1ly1glu9subwvnj22bc334hdu.jpg","2.jpg");
  4.         testThread02 t3 = new testThread02("https://wx1.sinaimg.cn/mw690/b4b0bcb1ly1glu9svt367j22bc334hdu.jpg","3.jpg");

  5.         new Thread(t1).start();
  6.         new Thread(t2).start();
  7.         new Thread(t3).start();
  8.     }
复制代码
并发问题
  1. package demo01;

  2. public class testThread04 implements Runnable{

  3.     private int ticketNums = 10;

  4.     @Override
  5.     public void run() {
  6.         while(true){
  7.             if (ticketNums<=0){
  8.                 break;
  9.             }
  10.             //模拟延迟
  11.             try {
  12.                 Thread.sleep(200);
  13.             } catch (InterruptedException e) {
  14.                 e.printStackTrace();
  15.             }
  16.             System.out.println(Thread.currentThread().getName()+"---->拿到了第"+ticketNums--+"票");
  17.         }
  18.     }

  19.     public static void main(String[] args) {
  20.         testThread04 t = new testThread04();
  21.         new Thread(t,"小明").start();
  22.         new Thread(t,"老师").start();
  23.         new Thread(t,"黄牛党").start();
  24.     }
  25. }
复制代码
发现问题,多个线程在操作同一个资源的情况下,线程不安全,数据紊乱。

实现Callable接口(了解)

静态代理

lambda表达式
为什么要使用lambda表达式
匿名内部类定义过多
可以让你的代码看起来很简洁
去掉一堆没有意义的代码,只留下核心逻辑
函数式接口的定义:任何接口,如果只包含唯一一个抽象方法,那么他就是一个函数式接口。对于函数式接口,我们就可以通过lambda表达式来创建该接口的对象。
推导lambda表达式
之前实现一个接口一般是编写实体类重写方法,在main函数里创建实体类对象交给接口接收,调用接口里重写的方法。
  1. package demo02;

  2. /**
  3. * 推导lambda表达式
  4. */
  5. public class TestLambda {

  6.     public static void main(String[] args) {
  7.         ILike like = new like();
  8.         like.lambda();
  9.     }
  10. }

  11. //1.定义一个函数式接口
  12. interface ILike{
  13.     void lambda();
  14. }

  15. //2.实现类
  16. class like implements ILike{
  17.     @Override
  18.     public void lambda() {
  19.         System.out.println("i like lambda");
  20.     }
  21. }
复制代码
把实现类挪到TestLambda类里,变成静态内部类。
  1. package demo02;

  2. /**
  3. * 推导lambda表达式
  4. */
  5. public class TestLambda {

  6.     //3.静态内部类
  7.     static class like implements ILike{
  8.         @Override
  9.         public void lambda() {
  10.             System.out.println("i like lambda");
  11.         }
  12.     }

  13.     public static void main(String[] args) {
  14.         ILike like = new like();
  15.         like.lambda();
  16.     }
  17. }

  18. //1.定义一个函数式接口
  19. interface ILike{
  20.     void lambda();
  21. }
复制代码
把静态内部类挪到main方法里,变成局部内部类
  1. package demo02;

  2. /**
  3. * 推导lambda表达式
  4. */
  5. public class TestLambda {

  6.     public static void main(String[] args) {
  7.         //4.局部内部类
  8.         class like implements ILike{
  9.             @Override
  10.             public void lambda() {
  11.                 System.out.println("i like lambda");
  12.             }
  13.         }

  14.         ILike like = new like();
  15.         like.lambda();
  16.     }
  17. }

  18. //1.定义一个函数式接口
  19. interface ILike{
  20.     void lambda();
  21. }
复制代码
把局部内部类再简化一下(不要类名),变成匿名内部类
  1. package demo02;

  2. /**
  3. * 推导lambda表达式
  4. */
  5. public class TestLambda {

  6.     public static void main(String[] args) {
  7.         ILike like = new ILike() {
  8.             @Override
  9.             public void lambda() {
  10.                 System.out.println("i like lambda");
  11.             }
  12.         };
  13.         like.lambda();
  14.     }
  15. }

  16. //1.定义一个函数式接口
  17. interface ILike{
  18.     void lambda();
  19. }
复制代码
因为接口ILike是函数式接口,只有唯一一个抽象方法,所以只用保留参数列表和方法体
  1. package demo02;

  2. /**
  3. * 推导lambda表达式
  4. */
  5. public class TestLambda {

  6.     public static void main(String[] args) {
  7.         ILike like = ()->{
  8.             System.out.println("i like lambda");
  9.         };
  10.         like.lambda();
  11.     }
  12. }

  13. //1.定义一个函数式接口
  14. interface ILike{
  15.     void lambda();
  16. }
复制代码
lambda最终简化
  1.     public static void main(String[] args) {
  2.         ILike like = ()->{ System.out.println("i like lambda");};
  3.         like.lambda();
  4.     }
复制代码
()->{ System.out.println("i like lambda");}是由匿名内部类简化来的,作用是创建了该接口的对象并且重写了抽象方法。
Thread实现了Runnable接口
我实现了Runnable接口
  1. public interface Runnable {
  2.     /**
  3.      * When an object implementing interface {@code Runnable} is used
  4.      * to create a thread, starting the thread causes the object's
  5.      * {@code run} method to be called in that separately executing
  6.      * thread.
  7.      * <p>
  8.      * The general contract of the method {@code run} is that it may
  9.      * take any action whatsoever.
  10.      *
  11.      * @see     java.lang.Thread#run()
  12.      */
  13.     public abstract void run();
  14. }
复制代码
找到Runnable接口,发现Runnable其实就是函数式实现类。所以重写Runnable可以用lambda化简。
一般情况下,自己写个类实现Runnable接口,重写Run方法,在main方法里创建实现类,并作为参数丢给Thread,再调用Thread的start方法。
  1. package demo03;

  2. public class test implements Runnable{

  3.     @Override
  4.     public void run() {
  5.         System.out.println("ddd");
  6.     }

  7.     public static void main(String[] args) {
  8.         test t = new test();
  9.         Thread thread = new Thread(t);
  10.         thread.start();
  11.     }
  12. }
复制代码
现在即不想专门写个实现类来实现Runnable接口,又想创建线程
  1. package demo03;

  2. public class test {

  3.     public static void main(String[] args) {
  4.         Thread thread = new Thread(new Runnable() {
  5.             @Override
  6.             public void run() {
  7.                 System.out.println("111");
  8.             }
  9.         });
  10.         thread.start();
  11.     }
  12. }
复制代码
  1. package demo03;

  2. public class test {

  3.     public static void main(String[] args) {
  4.         Thread thread = new Thread(()-> { System.out.println("111"); });
  5.         thread.start();
  6.     }
  7. }
复制代码
静态代理demo
  1. package demo03;

  2. public class staticProxy {
  3.     public static void main(String[] args) {
  4.         WeddingCompany weddingCompany = new WeddingCompany(new You());
  5.         weddingCompany.happyMarry();
  6.     }
  7. }

  8. class You implements Marry{
  9.     @Override
  10.     public void happyMarry() {
  11.         System.out.println("高兴的结婚");
  12.     }
  13. }

  14. class WeddingCompany implements Marry{

  15.     private Marry target;

  16.     public WeddingCompany(Marry target) {
  17.         this.target = target;
  18.     }

  19.     public void before(){
  20.         System.out.println("结婚前,布置酒店");
  21.     }

  22.     public void after(){
  23.         System.out.println("结婚后,收份子钱");
  24.     }

  25.     @Override
  26.     public void happyMarry() {
  27.         before();//同一个类中实例方法调用实例方法可以不用写类的引用。
  28.         target.happyMarry();
  29.         after();
  30.     }
  31. }

  32. interface Marry{
  33.     void happyMarry();
  34. }
复制代码
  1.         new Thread(()-> System.out.println("代理lambda")).start();

  2.         new WeddingCompany(new You()).happyMarry();//代理实现类

  3.         new WeddingCompany(()->{ System.out.println("代理lambda"); }).happyMarry();
复制代码
比较可知new Thread(()-> System.out.println("代理lambda")).start();可视为静态代理。
  1. //静态代理模式总结:
  2. //代理对象和真实对象都要实现同一个接口(Marry)
  3. //代理对象要代理真实角色

  4. //好处
  5.     //代理对象可以做很多真实对象做不了的事
  6.     //真实对象专注做自己的事
复制代码






本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|e小白

GMT+8, 2021-7-29 13:38 , Processed in 0.189751 second(s), 23 queries .

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表