java入门API_01之多线程上

多线程:

线程:一个进程可以有多个线程,比如app中的声音、弹幕、图像等;Thread -------------线程是不安全的
  同时:一个进程至少包含一个线程,不然没有存在的意义;--------------------------------------------------------------->线程,是CPU调度和执行的单位
进程:在操作系统中运行的程序就是进程,比如app; process
  程序:是指令和数据的有序集合,其本身没有任何运行的含义,是一个静态的概念
而进程,就是执行程序的一次"执行过程",它是一个动态的概念;--------------->进程,是系统资源分配的单位

注意:真正的多线程是指有多个cpu,即多核;
模拟的多线程:如服务器–》即在一个cpu的情况下,在同一时间点,cpu只能执行一个代码,因为切换的很快,就造成了同时执行的错觉!

线程:是独立的执行路径,在程序运行时即使没有创建线程,后台也会有多个线程,如主线程main,gc垃圾回收线程
    mian,为主线程,为系统的入口,用于执行整个程序;
一个进程中,如果开辟了多个线程,则线程的运行将由调度器(CPU就是调度器)安排调度,调度器是与操作系统紧密相关的,先后顺序是不能人为干扰的
对同一份资源操作时,会存在资源抢夺的问题 ---------->所以需要加入 并发 控制
线程会带来额外的开销,如cpu调度时间,并发控制开销!
每个线程在自己的工作内存交互,内存控制不当会造成数据不一致!
mian线程–主线程–也叫 用户线程
GC线程—jvm给的—叫守护线程
线程的创建方式有三种:
第一、继承Thread类
1、自定义线程类继承Thread类
2、重写run()方法,编写方法体
3、创建线程对象,调用start()方法启动线程

//自定义
class Test1 extends Thread{
    @Override
    public void run() {
        for (int i = 0; i < 1000; i++) {
            System.out.println("自定义线程,并重写run");
        }
    }
}
//3创建线程,调用
public static void main(String[] args) {
    new Test1().start();
}

总结:线程开启不一定立即执行,由调度器CPU调度执行;
第二、实现Runnable接口

class MyThreadDemo1 implements Runnable{
    @Override
    public void run() {
        for (int i = 0; i < 1000; i++) {
            System.out.println("创建Runnable接口的实例");
        }
    }
}

    public static void main(String[] args) {
        //创建Runnable接口的实现类-对象;
      Runnable r = new MyThreadDemo1();
        //创建线程对象,通过线程对象来开启我们的线程,这里是个代理——静态代理
        Thread t1 = new Thread(r);
        t1.start();
    }

第三、实现Callable接口(工作中可能会是 核心实现
基于第三种方式写的简单下载功能;

import org.apache.commons.io.FileUtils;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.concurrent.*;

public class CallableThread implements Callable<Boolean> {
    private String url;//保存图片地址
    private String file;//保存的文件名

    public CallableThread(String url, String file) {
        this.url=url;
        this.file=file;
    }

    @Override
    public Boolean call() {
        WebDownloade2 wd = new WebDownloade2();
        wd.downLoader(url,file);
        System.out.println("下载了文件名为"+file);
        return true;
    }

    public static void main(String[] args) {
        CallableThread ct = new CallableThread("https://s.cn.bing.net/th?id=OHR.NorthernCaracara_EN-CN8016443142_1920x1080.jpg&rf=LaDigue_1920x1080.jpg","2.jpg");
        CallableThread ct2 = new CallableThread("https://s.cn.bing.net/th?id=OHR.NorthernCaracara_EN-CN8016443142_1920x1080.jpg&rf=LaDigue_1920x1080.jpg","2.jpg");
        CallableThread ct3 = new CallableThread("https://s.cn.bing.net/th?id=OHR.NorthernCaracara_EN-CN8016443142_1920x1080.jpg&rf=LaDigue_1920x1080.jpg","2.jpg");
       //四步:第一步:创建执行服务、
        ExecutorService ser = Executors.newFixedThreadPool(3);//nThreads--->n个线程s-->可以理解为,n线程池--准备3个
        //第二步提交执行:
        Future<Boolean> submit1 = ser.submit(ct);
        Future<Boolean> submit2 = ser.submit(ct2);
        Future<Boolean> submit3 = ser.submit(ct3);
        //第三步 获取结果boolean值
        try {
            Boolean rs1 = submit1.get();
            Boolean rs2 = submit2.get();
            Boolean rs3 = submit3.get();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }finally {
            //第四步:关闭服务
            ser.shutdownNow();
        }
    }
}
//下载器
class WebDownloade2 {
    //下载方法
    public void downLoader(String url,String file){
        //需要使用一个文件工具类,导入commons-io-2.6 ---apache的;commons-io-2.6百度下载
        try {
            FileUtils.copyURLToFile(new URL(url), new File(file));

        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("IO异常,downloader方法出现异常");
        }
    }
}

Thread t=new Thread();

线程常用方法:

 t.currentThread();//获取主线程进行查看信息
  t.currentThread().getname();//获取线程名字
  t..getId();//满足条件:非空且唯一;获取线程的唯一标识
  t.start();//,启动线程
  t.sleep(5000);//睡眠5秒t
  t.getPriority();//获取,线程的优先级;  ----t.setPriority(3)----设置线程优先级-默认是5,最高max_10,最低min_1
  t.isInterrupted();//当前线程是否被中断
  t.isDaemon();//是否为守护线程,线程默认 都不是守护线程;-----设置true就是了,拓展实用
  t.isAlive();//是否活着
  
   t.join();//,当i==200时,,main不执行了,,让 TeJ1 来执行,插队,,很强势,少使用;
   Thread.yield();//礼让一下,退出cpu使用,让别的线程先执行,详见拓展实用

Thread—需要通过继承
    子类继承Thread类具备多线程能力,重写run()
    启动线程:子类对象。start();
    缺点:,不建议使用,局限,oop单继承,不能实现多实现;
Runnable—需要实现
    实现接口Runnable具备多线程能力 重写run()
    启动线程:传入目标对象+Thread对象.start();
    推荐使用:避免单继承局限性,灵活方便,方便同一个对象被多个子类实现(多个线程使用)

Callable----需要实现
    实现接口Callable接口设定<返回值>具备多线程能力,重写call,获取<返回值>
    然后使用四步:
    第一:创建执行服务()
    第二,提交执行
    第三,获取值
    第四,关闭服务,第一步对象
    好处:1、可以定义返回值-------2、可以抛出异常

线程的五大状态:
创建状态:new Threa();就是
就绪状态: new Thread().start()就是
阻塞状态: new Thread().sleep(5000);睡眠5秒 就是阻塞5秒
运行状态: new Thread().start();之后—就是
死亡状态: 线程结束或者中断;
常用方法: ------------------------------特别记忆 sleep===》每个对象都有一把锁,sleep不会释放锁;

Thread t=new Thread();
t.start();//就绪
t.sleep();//睡眠 -----------------------
t.setPriority(7);//线程优先级,,--默认是5,mian就是5,设置最高是10,最低是1
t.join();//等待该线程终止,才能抢占-----》类似 插队,,必须让该线程走完才行,
t.yield();//礼让,,,多个线程抢占,,该线程调用yield后,让其他的线程先执行
t.isAlive();//测试线程是否处于活动状态
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值