JAVA多线程

多任务

什么是多任务,比如边吃饭边玩手机,边开车边打电话,一个人同时干几件事,这就是多任务

进程

计算机同时执行多个进程,一般是同时运行多个软件

线程

使得在一个程序内部能拥有多个线程并行执行

多线程

同方向多条路供车行驶,厕所设立多个坑位,不会造成拥堵这就是多线程

Process与Thread

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


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


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


注意:很多多线程是模拟出来的,真正的多线程是指有多个cpu,即多核,如服务器。如果是模拟出来的多线程,即在一个cpu的情况下,在同一个时间点,cpu只能执行一个代码,因为切换的很快,所以就有同时执行的错局。

核心理念

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


在程序运行时,即使没有自己创建线程,后台也会有多个线程,如主线程,gc线程;

main()称之为主线程,为系统的入口,用于执行整个程序;


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


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

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


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

线程创建

Thread 、Runnable 、Callable

Thread class:继承Thread 类(重点)

Runnable接口:实现Runnable接口(重点)

Callable接口:实现Callable接口(了解)

Thread

自定义线程类继承Thread类(养成习惯:继承完Thread类就重写run方法)

重写run()方法,编写执行代码

创建线程对象,调用start()方法启动线程

public class test extends Thread{
    //重写run方法
    //快捷重写:打run就会提示
    @Override
    public void run() {
        //线程体
        for (int i = 0; i < 10; i++) {
            System.out.println("我是第"+ i +"个");
        }
       // super.run();
    }
    //mian方法主线程
    public static void main(String[] args) {
        //创建线程对象
        test test = new test();
        //启动线程
        test.start();
    }
}

图片下载

注意提前导入需要的包:

<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.2</version>
</dependency>
import org.apache.commons.io.FileUtils;

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

//练习Thread实现多线程同步下载图片
public class test extends Thread{
        //储存url
        private String url;
        //储存文件名
        private String name;

        public test(String url, String name){
                //把传进来的url赋值给private String url
                this.url = url;
                //把传进来的name赋值给private String name
                this.name = name;

        }
        //线程执行方法
        @Override
        public void run() {
                //创建内部类
                webdownload webdownload = new webdownload();
                //调用内部类中的方法,把url和name传进去
                webdownload.download(url,name);
        }
        //创建主线程
        public static void main(String[] args) {
                //把url和name传进test方法中,再由test方法中的this赋值给定义的属性
                test test1 = new test("https://img1.baidu.com/it/u=3217543765,3223180824&fm=253&fmt=auto&app=120&f=JPEG?w=1200&h=750", "hua.jpg");
                test test2 = new test("https://img2.baidu.com/it/u=436635185,1433075744&fm=253&fmt=auto&app=138&f=JPEG?w=666&h=500", "shan.jpg");
                test test3 = new test("https://img0.baidu.com/it/u=857510153,4267238650&fm=253&fmt=auto&app=120&f=JPEG?w=1200&h=675", "mao.jpg");
                //开启线程
                test1.start();
                test2.start();
                test3.start();
        }
}

//内部类
class webdownload{
        //下载方法,需要一个地址(url)和一个名字(name)
        public void download(String url,String name){
                //捕获异常
                try {
                        //使用FileUtils.copyURLToFile方法下载图片
                        FileUtils.copyURLToFile(new URL(url),new File(name));
                } catch (IOException e) {
                       e.printStackTrace();
                       //报错提示
                       System.out.println("download异常");
                }

        }
}

实现Runable接口

//实现接口
public class test implements Runnable{
    //重写方法
    @Override
    public void run() {
        //简单循环
        for (int i = 0; i < 10; i++) {
            System.out.println("Runnable" + i);
        }
    }
    //主线程
    public static void main(String[] args) {
        //new一个test
        test test = new test();
        //new一个线程,把test里的run方法放进去
        Thread thread = new Thread(test);
        //启动线程
        thread.start();
        for (int i = 0; i < 10; i++) {
            System.out.println("main" + i);
        }
    }
}

并发问题

例子1:龟兔赛跑

public class test2 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(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            boolean flag = gameOver(i);
            if (flag){
                break;
            }

            System.out.println(Thread.currentThread().getName()+"跑了"+i+"步");
        }
    }
    private boolean gameOver(int a ){
        if (winner != null){
            return true;
        }{
            if (a >= 100){
                winner = Thread.currentThread().getName();
                System.out.println("胜利者"+winner);
                return true;
            }
        }
        return false;
    }

    public static void main(String[] args) {
        test2 test2 = new test2();
        new Thread(test2,"乌龟").start();
        new Thread(test2,"兔子").start();
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值