多线程学习(一)

第一节、线程的概述(目录)

1、线程的简介
2、线程的实现
3、线程的状态
4、线程的同步
5、线程的通信问题
6、高级主题

第二节、线程、进程、多线程

1、一个进程可以有多个线程,如视频中同时有声音,图像,字幕,弹幕等…
2、进程就相当于一个程序,程序相当于代码,一个静态的概念,进程就是将程序跑起来,就是程序执行的过程,哪怕进程什么都不干也是有一个主线程的main,跟gc线程。
3、进程中包含多个线程,如视频中同时有声音,图像,字幕,弹幕等,我们现在的线程都是一个CPU模拟出来的,只不过来回切换的很快(比如边吃饭边玩手机,其实不是同时进行的),真正的多线程是由多个CPU多核来实现完成的
4、在一个进程中,多个线程的调度是由CPU进行调度的,先后顺序不能人为的进行干预
5、对同一个资源操作时,会出现资源抢夺的问题,需要进行并发的控制

第三节、线程的实现继承Thread类

package thread;

public class ThreadDemo extends Thread {
    @Override
    public void run() {
        for (int i = 0; i <= 200; i++) {
            System.out.println("ThreadDemo线程!第"+i+"次执行!");
        }
    }

    public static void main(String[] args) {
        ThreadDemo threadDemo = new ThreadDemo();
        threadDemo.start();
        for (int i = 0; i <= 1000; i++) {
            System.out.println("main主线程!第"+i+"次执行!");
        }
    }
}

我们可以看到这里的执行过程,两段线程是交替进行的,说明已经使用到了多线程

第四节、使用多线程(继承Thread类)同时下载多个网图 实例

package wangtu;

import org.apache.commons.io.FileUtils;

import java.io.File;
import java.io.IOException;
import java.net.URL;

public class ThreadDemo extends Thread{
    private String url;
    private String name;

    public ThreadDemo(String url, String name) {
        this.url = url;
        this.name = name;
    }

    @Override
    public void run() {
        DownLoader downLoader = new DownLoader();
        downLoader.download(this.url,this.name);
        String FileName[] = new String(this.name).split("\\\\");
        System.out.println("下载网络图片:"+FileName[FileName.length-1]);
    }

    public static void main(String[] args) {
        ThreadDemo threadDemo1 = new ThreadDemo("https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=1913756807,1163305347&fm=26&gp=0.jpg","D:\\upload\\1.jpg");
        ThreadDemo threadDemo2 = new ThreadDemo("https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=3267870809,2513733619&fm=26&gp=0.jpg","D:\\upload\\2.jpg");
        ThreadDemo threadDemo3 = new ThreadDemo("https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=2998896561,1019231785&fm=26&gp=0.jpg","D:\\upload\\3.jpg");
        threadDemo1.start();
        threadDemo2.start();
        threadDemo3.start();
    }
}

class DownLoader{
    public void download(String url,String name){
        try {
            FileUtils.copyURLToFile(new URL(url),new File(name));
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println();
        }
    }
}

从运行结果我们可以看出,是使用多线程交替执行的方式下载的多个网图
在这里插入图片描述

第五节、用Runnable接口来实现多线程

package thread;

public class RunnableDemo implements Runnable{

    @Override
    public void run() {
        for (int i = 0; i < 20; i++) {
            System.out.println("RunnableDemo线程,第"+i+"次执行!");
        }
    }

    public static void main(String[] args) {
        RunnableDemo runnableDemo = new RunnableDemo();
        //注意这里与继承Thread类不同,继承Thread类的方式是:
        // ThreadDemo threadDemo = new ThreadDemo();
        //threadDemo.start();

        //实现Runnable接口是先创建刚刚实现了Runnable接口的类的实例,然后创建一个新的Thread,将刚刚创建的实例放进去
        new Thread(runnableDemo).start();
        for (int i = 0; i < 200; i++) {
            System.out.println("main主线程,第"+i+"次执行!");
        }
    }
}

我们可以看到通过实现Runnable接口同样也得到了跟继承Thread类一样的交替执行的效果
在这里插入图片描述

第六节、并发问题 买票实例

package thread;

public class RunnableDemo01 implements Runnable{

    private int ticketNums = 10;

    @Override
    public void run() {
        while (true){
            if(ticketNums<=0){
                break;
            }
            System.out.println(Thread.currentThread().getName()+"拿到了第" + ticketNums-- + "张票!");
        }
    }

    public static void main(String[] args) {
        RunnableDemo01 demo01 = new RunnableDemo01();
        RunnableDemo01 demo02 = new RunnableDemo01();
        RunnableDemo01 demo03 = new RunnableDemo01();

         new Thread(demo01,"小明").start();
        new Thread(demo02,"小红").start();
        new Thread(demo03,"老师").start();
    }
}

通过结果我们可以发现,出现了资源抢夺的并发问题
在这里插入图片描述

第七节、龟兔赛跑 实例

package thread;

public class RunnableDemo03 implements Runnable{

    private int bushu = 100;
    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 b = GameOver(i);
            if(b){
                break;
            }

            System.out.println(Thread.currentThread().getName()+"跑了"+i+"步!");
        }
    }

    public static void main(String[] args) {
        RunnableDemo03 demo01 = new RunnableDemo03();
        RunnableDemo03 demo02 = new RunnableDemo03();

        new Thread(demo01,"兔子").start();
        new Thread(demo02,"乌龟").start();
    }

    public boolean GameOver(int bushu){
        if(this.winner!=null){
            return true;
        }{
            if(bushu>=100){
                winner = Thread.currentThread().getName();
                System.out.println("winner is " + winner);
                return true;
            }
            return false;
        }
    }
}

我们可以看到最后是乌龟赢了
在这里插入图片描述

第八节、实现Callable接口

package thread;

import java.util.concurrent.*;

public class CallableDemo implements Callable {

    private int ticketNums = 10;

    @Override
    public Boolean call() {
        while (true){
            if(ticketNums<=0){
                break;
            }
            System.out.println(Thread.currentThread().getName()+"拿到了第" + ticketNums-- + "张票!");
        }
        return true;
    }

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        CallableDemo demo01 = new CallableDemo();
        CallableDemo demo02 = new CallableDemo();
        CallableDemo demo03 = new CallableDemo();

        ExecutorService executorService = Executors.newFixedThreadPool(3);

        Future<Boolean> submit1 = executorService.submit(demo01);
        Future<Boolean> submit2 = executorService.submit(demo02);
        Future<Boolean> submit3 = executorService.submit(demo03);

        Boolean b1 = submit1.get();
        Boolean b2 = submit2.get();
        Boolean b3 = submit3.get();

        executorService.shutdown();
    }
}

一样实现了多线程的交替式执行过程
在这里插入图片描述

第九节、静态代理实现 婚礼实例

package thread;


public class StaticProxy{
    public static void main(String[] args) {
        WeddingCompany weddingCompany = new WeddingCompany(new You());
        weddingCompany.happyMarry();
    }
}

interface Marry{
    void happyMarry();
}

class You implements Marry{
    @Override
    public void happyMarry() {
        System.out.println("小明结婚了!!!");
    }
}

class WeddingCompany implements Marry{

    private Marry marry;

    public WeddingCompany(Marry marry) {
        this.marry = marry;
    }

    @Override
    public void happyMarry() {
        after();
        this.marry.happyMarry();
        before();
    }

    public void after(){
        System.out.println("结婚后,收尾款!");
    }
    public void before(){
        System.out.println("结婚前,办酒席!");
    }
}

我们可以看到,我们并没有调用You类实例的happyMarry()方法,通过静态代理的模式自动调用了You的happyMarry()方法
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值