多线程学习

多线程学习

创建线程的方式
创建线程的方法一

继承Thread类,重写run()方法,调用start开启线程

public class TestThread01 extends Thread{
    @Override
    public void run() {
       // run方法线程体
        for (int i = 0; i < 20; i++) {
            System.out.println("我在看代码"+i);
        }
    }


    public static void main(String[] args) {

        // main线程体 , 主线程

        // 创建一个线程对象
        TestThread01 tt = new TestThread01();
        // 调用start()方法开启线程
        tt.start();


        for (int i = 0; i < 20; i++) {
            System.out.println("我在学习"+i);
        }
    }

创建线程的方法二

实现Runnable接口,重写run()方法,执行线程需要丢入runable接口实现类,调用start方法。

public class TestThread03 implements Runnable{
    @Override
    public void run() {
        // run方法线程体
        for (int i = 0; i < 20; i++) {
            System.out.println("我在看代码"+i);
        }
    }
    public static void main(String[] args) {
        // 创建runnable接口的实现类对象
        TestThread03 tt3 = new TestThread03();
        // 创建线程对象,通过线程对象来开启我们的线程(代理)
//        Thread thread = new Thread(tt3);
//        thread.start();
        new Thread(tt3).start();
        for (int i = 0; i < 20; i++) {
            System.out.println("我在学习"+i);
        }
    }
创建线程的方法三

实现callable接口,callable的好处,可以定义返回值,可以抛出异常。

public class TestCallable implements Callable<Boolean> {
    private String url;// 网络图片的地址
    private String name;// 保存文件的文件名
    public TestCallable(String url,String name){
        this.url= url;
        this.name= name;
    }
    // 下载图片线程的执行体
    @Override
    public Boolean  call(){
        WebDownLoader wdl = new WebDownLoader();
        wdl.downlocader(url,name);

        System.out.println("下载的文件名为:"+name);
        return  true;
    }
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        TestCallable tt2= new TestCallable("url","2.jpg");
        TestCallable tt3= new TestCallable("url","3.jpg");
        TestCallable tt4= new TestCallable("url","4.jpg");
        // 创建执行服务
        ExecutorService es = Executors.newFixedThreadPool(3);
        // 提交执行
        Future<Boolean> r1= es.submit(tt2);
        Future<Boolean> r2= es.submit(tt3);
        Future<Boolean> r3= es.submit(tt4);
        // 获取结果
        boolean rs1 = r1.get();
        boolean rs2 = r2.get();
        boolean rs3 = r3.get();

        // 关闭服务
        es.shutdownNow();
    }
}
// 下载器
class  WebDownLoader{
    // 下载方法
    public void downlocader(String url,String name){
        try {
            FileUtils.copyURLToFile(new URL(url),new File(name));
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("IO异常,downlocader方法出现问题");
        }
    }

静态代理

静态代理模式:真实对象和代理对象都实现同一个接口。代理对象要代理真实角色;好处在于代理对象可以做很多真实对象做不了的事情,真实对象可以专注于做自己的事情

public class StaticProxy {
    public static void main(String[] args) {
       WeddingCompany wc= new WeddingCompany(new You());
        wc.HappyMarry();
    }
    }
interface Marry{
    void HappyMarry();
}
class You implements Marry{
        @Override
        public void HappyMarry() {
            System.out.println("结婚很开心");
        }
    }
    // 代理角色,帮助你结婚
      class WeddingCompany  implements Marry{
            private Marry target;
        public WeddingCompany(Marry target){
            this.target =target;
        }
          @Override
          public void HappyMarry() {
              before();
              this.target.HappyMarry();
              after();
          }
          private void before(){
              System.out.println("结婚之前布置现场");
          }
          private  void after(){
              System.out.println("结婚之后结尾款");
          }
      }

Lambda表达式

推导lambda表达式

public class TestLambda01 {
    // 3.静态内部类
  static   class Like2 implements ILike {
        @Override
        public void Lambda() {
            System.out.println(" i like lambda2");
        }
    }
    public static void main(String[] args) {
        ILike like = new Like();
        like.Lambda();

        like= new Like2();
        like.Lambda();

        // 4.局部内部类
           class Like3 implements ILike {
            @Override
            public void Lambda() {
                System.out.println(" i like lambda3");
            }
        }
                 like = new Like3();
           like.Lambda();

           // 5.匿名内部类,没有类的名称,必须借助接口或者父类
        like = new  ILike() {
            @Override
            public void Lambda() {
                System.out.println(" i like lambda4");
            }
        };
        like.Lambda();

        // 6.用Lambda简化
        like = ()-> {
            System.out.println(" i like lambda5");
        };
        like.Lambda();
    }
}
 // 1.定义一个函数式接口
interface ILike{
    void  Lambda();
 }
  // 2.实现类
class Like implements ILike {
      @Override
      public void Lambda() {
          System.out.println(" i like lambda");
      }
  }

最终结果

// 最终 lambda表达式
public class TestLambda03 {
    public static void main(String[] args) {
        Test test= null;

        test = (a,b)->{
            System.out.println("乌拉乌拉"+a);
            System.out.println("乌拉乌拉"+b);
        };
        test.test("jie","wan");
    }
}

interface Test{
    void test(String a ,String b);
}

join方法(插队)和延时方法
/ 测试join方法 插队
public class TestJoin  implements Runnable{

    @Override
    public void run() {
        for (int i = 0; i < 200; i++) {
            System.out.println("vip来了"+i);
        }
    }

    public static void main(String[] args) throws InterruptedException {

        // 启动线程
        TestJoin tj= new TestJoin();
        Thread thread = new Thread(tj);

        thread.start();
        // 主线程
        for (int i = 0; i < 1000; i++) {
            if (i==300){
                thread.join();//插队
            }
            System.out.println("main"+i);
        }
    }

利用延时模拟倒计时

  public static void  tenDown() throws InterruptedException {
        int num = 10;
        while (true){
            Thread.sleep(1000);
            System.out.println(num--);
            if (num<=0){
                break;
            }
        }
    }
stop方法和Yield方法
public class TestStop implements Runnable {
    // 1. 设置一个标志位
    private boolean flag =true;

    @Override
    public void run() {
        int i = 0;
        while (flag){
            System.out.println("rum.....Thread"+i++);
        }

    }
    // 2.设置一个公开的方法停止线程,转换标志位

    public void stop(){
        this.flag = false;
    }
    public static void main(String[] args) {
        TestStop ts= new TestStop();

        new Thread(ts).start();
        for (int i = 0; i < 1000; i++) {
            System.out.println("main"+i);
            if(i==900){
                // 调用stop方法切换标志位,让线程停止
                ts.stop();
                System.out.println("停止");
            }


// 测试礼让线程
// 礼让不一定成功,看CPU心情
public class TestYield {
    public static void main(String[] args) {
        MyYield myYield = new MyYield();

        new Thread(myYield,"3").start();
        new Thread(myYield,"4").start();
        new Thread(myYield,"5").start();
        new Thread(myYield,"6").start();


    }
}

class MyYield implements Runnable{

    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName()+"开始");

        Thread.yield();

        System.out.println(Thread.currentThread().getName()+"结束");
    }

Yield:礼让不一定成功,看CPU心情

线程锁

线程锁:主要用来给方法、代码块加锁。当某个方法或者代码块使用锁时,那么在同一时刻至多仅有有一个线程在执行该段代码。当有多个线程访问同一对象的加锁方法/代码块时,同一时间只有一个线程在执行,其余线程必须要等待当前线程执行完之后才能执行该代码段。但是,其余线程是可以访问该对象中的非加锁代码块的。

public class TestLock {
    public static void main(String[] args) {
        TestLock2 tl2= new TestLock2();

        new Thread(tl2).start();
        new Thread(tl2).start();
        new Thread(tl2).start();

    }
}
class  TestLock2 implements Runnable{
        int ticketNums= 10;
        // 定义lock锁
private final     ReentrantLock lock = new ReentrantLock();

    @Override
    public void run() {
        while (true){
          try {
              lock.lock();// 加锁

            if (ticketNums>0){
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(ticketNums--);
            }
        }finally {
              // 解锁
              lock.unlock();
          }
        }
    }
}

生产者消费者模型

管程法:利用缓冲区来实现。

class  SynContainer{
    // 需要一个容器大小
    Chicken[] chickens =new Chicken[10];
    // 容器计数器
    int counts = 0;

    // 生产者放入产品
    public synchronized void  push(Chicken chicken){
        //如果容器满了,就需要等待消费者消费
        if (counts==chickens.length){
            //通知消费者消费,生产者等待
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        //如果没有满,生产者就需要生产产品放入
        chickens[counts]=chicken;
        counts++;
        // 通知消费者消费
        this.notifyAll();

    }

    // 消费者消费产品
    public synchronized Chicken pop(){
        if (counts==0){
            //等待生产者生产,消费者等待
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        // 如果可以消费
        counts--;
        Chicken chicken = chickens[counts];

        // 吃完了等待生产者生产
        this.notifyAll();
        return chicken;
    }

信号灯法:标志位解决。

lass TV{
    // 演员表演,观众等待
    // 观众观看,演员等待
    String voice;//表演的节目
    boolean flag =true;

    // 表演
    public synchronized void play(String voice){

        if (!flag){
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println("演员表演了:"+voice);
        // 通知观众观看
        this.notifyAll();// 通知唤醒
        this.voice = voice;
        this.flag = !this.flag;
    }

    // 观看
    public synchronized void  watch()  {
        if (flag){
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println("观看了:"+voice);
        // 通知演员表演
        this.notifyAll();
        this.flag = !this.flag;
    }

线程池

public class TestPool {
    public static void main(String[] args) {
        // 1.创建服务,创建线程池
        // newFixedThreadPool 参数为:线程池大小
        ExecutorService service = Executors.newFixedThreadPool(10);

        // 执行
        service.execute(new MyThread());
        service.execute(new MyThread());
        service.execute(new MyThread());
        service.execute(new MyThread());
        service.execute(new MyThread());

        // 2. 关闭连接
        service.shutdown();

    }
}
class MyThread implements Runnable{

    @Override
    public void run() {

            System.out.println(Thread.currentThread().getName());

    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值