栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

JAVA多线程(一)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

JAVA多线程(一)

目录

一、进程与线程

二、进程与线程的区别

三、线程的实现

四、线程的生命周期

五、线程小练习

总结以上就是今天要讲的内容,本文仅仅简单介绍了线程的使用,而线程还有很多常用的函数和方法。且听下回分解。





一、进程与线程

1.进程的概念:进程就是正在进行的程序,他会占用对应的内存区域,由CPU执行与计算。

2.线程的概念:线程是操作系统OS能够进行运算调度的最小单位,它被包含在进程之中,是进程中的实际运作单位.
一个进程可以开启多个线程,其中有一个主线程来调用本进程中的其他线程。
我们看到的进程的切换,切换的也是不同进程的主线程
多线程可以让同一个进程同时并发处理多个任务,相当于扩展了进程的功能。




二、进程与线程的区别

从java内存区域上来说,线程在堆和方法区是线程共享的,本地方法栈、虚拟机栈和程序计数器是线程私有的。

  1. 根本区别:进程是操作系统资源分配的基本单位,线程是处理器任务调度和执行的基本单位。内存中运行的每个.exe程序都是一个进程。

  2. 资源开销:进程开销大,但是资源的管理和保护好;而线程是资源开销小,但是不利于资源的管理和保护。

  3. 一个进程包含至少一个线程,也可以包含多个线程,各个进程是相互独立的,而线程不一定,同一个进程中的线程可能相互影响。

三、线程的实现

1.继承Thread类


class MyThread extends Thread {

    public void run(){
        for (int i=0;i<100;i++){
            System.out.println(MyThread.currentThread().getName()+"执行了"+i);
        }
    }
}

class ThreadDemo{
    public static void main(String[] args) throws InterruptedException {
        MyThread mythread = new MyThread();

        MyThread mythread1 = new MyThread();

        mythread.start();

        for (int i=0;i<100;i++){
            System.out.println(MyThread.currentThread().getName()+"执行了"+i);
        }

        mythread1.start();

    }
}

2.Runnable接口

class MyRunnable implements Runnable {

    @Override
    public void run() {
        for (int i=0;i<100;i++){
            System.out.println(MyThread.currentThread().getName()+"--"+i);
        }
    }
}

class RunnableDemo{
    public static void main(String[] args) {
        MyRunnable myRunnable = new MyRunnable();
        Thread thread = new Thread(myRunnable);

        thread.start();
    }
}

3.Callable接口

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

class MyCallable implements Callable {

    @Override
    public Long call() throws Exception {
        long sum = 0;
        for (long i = 0;i<1000000000L;i++){
            sum += i;
        }
        return sum;
    }
}

class CallableDemo{
    public static void main(String[] args) {
        FutureTask tasK = new FutureTask<>(new MyCallable());

        Thread thread = new Thread(tasK);

        thread.start();
        System.out.println("----等待结果----");
        try {
            System.out.println(tasK.get());
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }
}

4.线程池

线程池其实就是一个 容纳多个线程的容器 ,其中的线程可以反复使用,省去了频繁创建线程对象的操作 ,无需反复创建线程而消耗过多资源。

四、线程的生命周期

线程的生命周期会经历以下几个状态:

新建:new创建线程对象时

就绪:调用 start()方法时

运行:调用 run()方法时

阻塞: 多种原因可导致阻塞如(sleep,执行IO操作,wait等)

死亡:执行完run后

五、线程小练习

1.设计两个线程,一个线程负责打印1~100以内所有的偶数;然后,另外一个线程负责打印1~100以内所有的奇数。测试时,分别设置线程的优先级,观察执行的顺序。

class Zy1 {
    public static void main(String[] args) {
        new Thread(()->{
            for (int i = 0; i <100 ; i++) {
                if(i%2==0){
                    System.out.println(Thread.currentThread().getName()+"偶数--"+i);
                }
            }
        }).start();
        new Thread(()->{
            for (int i = 0; i <100 ; i++) {
                if(i%2!=0){
                    System.out.println(Thread.currentThread().getName()+"奇数--"+i);
                }
            }
        }).start();
    }
}

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

public class Zy2 {
    public static void main(String[] args) {
        new Thread(() -> {
            File file = new File("D:\Study\aaa.txt");
            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();
            }

        }

    }

}

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

public class Zy3 {
    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 e1) {
                    e1.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();
    }

}

4.多线程模拟龟兔赛跑:乌龟和兔子进行1000米赛跑,兔子前进5米,乌龟只能前进1米。但兔子每20米要休息500毫秒,而乌龟是每100米休息500毫秒。谁先到终点就结束程序,并显示获胜方

public class Zy4 {
    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;
}




总结
以上就是今天要讲的内容,本文仅仅简单介绍了线程的使用,而线程还有很多常用的函数和方法。且听下回分解。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/642752.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号