java线程初始

目标

  1. 线程的概念

    1. 线程和进程的区别

    2. 串行、并行和并发的概念

  2. 线程的实现

  3. 线程的生命周期

  4. 线程的常用方法

线程的概念

程序和进程的区别

程序是静态的,进程是动态的,程序是存储在某种介质上的二进制代码,进程对应了程序的执行过程,系统不需要为一个不执行的程序创建进程,一旦进程被创建,就处于不断变化的动态过程中,对应了一个不断变化的上下文环境。

程序是永久的,进程是暂时存在的。程序的永久性是相对于进程而言的,只要不去删除它,它可以永久的存储在介质当中。

进程与线程的区别

(1)调度:线程作为调度和分配的基本单位,进程作为拥有资源的基本单位

(2)并发性:不仅进程之间可以并发执行,同一个进程的多个线程之间也可并发执行
​
(3)拥有资源:进程是拥有资源的一个独立单位,线程不拥有系统资源,但可以访问隶属于进程的资源.
​
(4)系统开销:在创建或撤消进程时,由于系统都要为之分配和回收资源,导致系统的开销明显大于创建或撤消线程时的开销。

串行,并发和并行

  • 串行 多个指令从上到下依次执行,

  • 并发 每个线程会经行抢占时间片,所以会有来回切换的效果 但不是同时进行,没有时间安排会是等待的状态

  • 并行 多个cpu内核同时执行多个线程,相互不影响且同时进行

线程的实现

java四种实现线程的方式

  1. 继承Thread类

  2. 实现Runnable接口

  3. 实现Callable接口

  4. 使用线程池

继承Thread类

  1. 继承Thread类

  2. 重写run方法

  3. 调用start启动线程

案例实现1

设计两个线程,一个线程负责打印1~100以内所有的偶数;然后,另外一个线程负责打印1~100以内所有的奇数。


class Thread1 extends Thread{
    public void run(){
        for (int i = 0; i <=100 ; i+=2) {
            System.out.println(Thread2.currentThread().getName()+"奇数"+i);
            
        }
    }
}
​
class Thread2 extends Thread{
    public void run(){
        for (int i = 0; i <=100 ; i+=2) {
            System.out.println(Thread2.currentThread().getName()+"偶数"+i);
​
        }
    }
}
public class ZuoYe1 {
​
    public static void main(String[] args) {
        Thread1 t1=new Thread1();
        Thread2 t2=new Thread2();
        t1.setPriority(Thread.MIN_PRIORITY);
        t2.setPriority(Thread.MAX_PRIORITY);
        t1.start();
        t2.start();
​
    }
}

案例二

实现一个线程,用于扫描某个目录下的所有文本文件(包括:java、txt、html),并将文字内容打印出来。

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
​
​
public class ZuoYe02 {
    public static void main(String[] args) {
        new Thread(() -> {
            File file = new File("D:\\workspace03");
            readFile(file);
        }).start();
​
    }
​
    public static void readFile(File f) {
​
        if (f.isDirectory()) {
            File[] files = f.listFiles();
            if (files != null) {
                for (File file : files) {
                    readFile(file);
                }
            }
        } else {
            System.out.println(f.getName());
            //读文件
            try {
                //得到文件
                //得到文件读取的字符流
                FileReader fileReader = new FileReader(f);
                //得到带缓冲字符流
                BufferedReader bufferedReader = new BufferedReader(fileReader);
                String readLine = null;
                while((readLine = bufferedReader.readLine()) != null){
                    System.out.println(readLine);
                }
​
                fileReader.close();
                bufferedReader.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
​
        }
​
    }
​
}

案例三

某人正在看电视连续剧,从第1~88集,看到第10集时,来了一个送快递的,收完快递后后,继续看电视。

public class ZuoYe03 {
    public static void main(String[] args) {
        new Thread(()->{
            for (int i = 1; i <89 ; i++) {
                System.out.println(Thread.currentThread().getName() + "===" + "看到了第" + i + "级");
                try{
                    Thread.sleep(300);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                if(i==10){
                    Thread t1=new Thread(new Runnable() {
                        @Override
                        public void run() {
                            System.out.println(Thread.currentThread().getName() + "===" + "送快递的来了");
                            try{
                                Thread.sleep(5000);
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                            System.out.println(Thread.currentThread().getName() + "===" + "快递拿完了");
                        }
                    });
                    t1.start();
                    try {
                        t1.join();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }).start();
    }
}

案例四

  1. 多线程模拟龟兔赛跑:

乌龟和兔子进行1000米赛跑,兔子前进5米,乌龟只能前进1米。

但兔子每20米要休息500毫秒,而乌龟是每100米休息500毫秒。

谁先到终点就结束程序,并显示获胜方

public class ZuoYe04 {
    public static void main(String[] args) {
        Result r = new Result();
        new Thread(() -> {
​
            for (int i = 1; i <= 1000; i++) {
​
                System.out.println("乌龟跑了" + i + "米");
                try {
                    Thread.sleep(1);
                } catch (InterruptedException e1) {
                    e1.printStackTrace();
                }
                if (i >= 1000) {
                    r.isWin = true;
                    System.out.println("乌龟胜利了" + i);
                    break;
                }
                if (i % 100 == 0) {
                    try {
                        System.out.println("乌龟在"+i+"米处开始休息");
                        Thread.sleep(500);
​
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
​
        }).start();
​
        new Thread(() -> {
            int m = 0;
            for (int j = 1; j <= 200; j++) {
                if(r.isWin){
                    System.out.println("兔子跑了" + m + "米............");
                    break;
                }
                m += 5;
                System.out.println("兔子跑了" + m + "米");
                try {
                    Thread.sleep(1);
                } catch (InterruptedException e1) {
                    e1.printStackTrace();
                }
                if (m >= 1000) {
                    System.out.println("兔子胜利了" + j);
​
                }
                if (m % 20 == 0) {
                    try {
                        System.out.println("兔子在"+j*5+"米处开始休息");
                        Thread.sleep(500);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }).start();
​
    }
​
}
class Result{
    boolean isWin = false;
}

线程的生命周期

线程几种状态:

  • 新建 NEW

  • 准备/就绪 START

  • 运行 RUNNING

  • 阻塞 BLOCKING

  • 死亡 DEAD

 

线程的常用方法

常用方法

方法 介绍
start() 启动
stop() 停止(禁用,可能导致线程死锁等问题),停止线程可以让run执行结束
String getName() 获得线程的名字
setName(String) 设置线程名字
sleep(long) 进入睡眠,毫秒
setPriority(int) 设置线程的优先级(1~10从低到高)越高抢CPU几率更高
setDaemon(boolean) 设置为后台线程 true ,后台线程是为其它线程服务的,如果没有其它线程存在,就自动死亡;使用案例:GC就是一种后台线程
join() 线程的加入(合并)让其它线程先执行完,再执行自己的指令

个人总结

上述归纳算是步入线程学习的门槛,要想能够熟练运用还是得多敲多练,‘

书山有路勤为径学海无涯苦作舟

Supongo que te gusta

Origin blog.csdn.net/weixin_46701812/article/details/121788861
Recomendado
Clasificación