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

Java多线程

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

Java多线程

1.多线程概述

package com.java.javase.Thread;
public class chapterFirst {

多线程
 *         1、什么是进程?什么是线程?
 *             进程是一个应用程序(1个进程是一个软件)
 *             线程是一个进程中的执行场景/执行单元
 *             一个进程可以启动多个线程
 *
 *         2、对于java程序来说,当在DOS命令窗口中输入:
 *             java HelloWorld 回车之后会先启动JVM,而JVM就是一个进程
 *             JVM再启动一个主线程调用main方法
 *                再启动一个垃圾回收线程负责看护,回收垃圾
 *             最起码,现在的java程序中至少有两个线程并发,一个是垃圾回收线程,一个是执行main方法的主线程
 *
 *         3、进程和线程是什么关系?举个例子
 *             阿里巴巴:进程
 *             马云:阿里巴巴的一个线程
 *             童文红:阿里巴巴的一个线程
 *
 *             京东:进程
 *             强东:京东的一个线程
 *             妹妹:京东的一个线程
 *
 *             进程可以看做是现实生活当中的公司
 *             线程可以看做是公司当中的某个员工
 *
 *             注意:
 *             进程A和进程B的内存独立不共享(阿里巴巴和京东的资源不会共享的!)
 *             魔兽游戏是一个进程
 *             酷狗音乐是一个进程
 *             这两个进程是独立的,不共享资源
 *
 *             线程A和线程B呢?
 *             在java语言中:
 *             线程A和线程B,堆内存和方法区内存共享
 *             但是栈内存独立,一个线程一个栈
 *
 *             假设启动10个线程,会有10个栈空间,每个栈和每个栈之间,互不干扰,各自执行各自的,这就是多线程并发
 *
 *             火车站,可以看做是一个进程
 *             火车站中的每一个售票窗口可以看做是一个线程
 *             我在窗口1购票,你可以在窗口2购票,你不需要等我,我也不需要等你
 *             所以多线程并发可以提高效率
 *
 *             java中之所以有多线程机制,目的就是为了提高程序的处理效率
 *
 *         4、思考一个问题:
 *             使用了多线程机制之后,main方法结束,是不是有可能程序也不会结束?
 *             main方法结束只是主线程结束了,主栈空了,其它的栈(线程)可能还在压栈弹栈
 *
 *         5、分析一个问题:对于单核的CPU来说,真的可以做到真正的多线程并发吗?
 *             对于多核的CPU电脑来说,真正的多线程并发是没问题的
 *             4核CPU表示同一个时间点上,可以真正的有4个进程并发执行
 *
 *             什么是真正的多线程并发?
 *             t1线程执行t1的
 *             t2线程执行t2的
 *             t1不会影响t2,t2也不会影响t1————多线程并发
 *
 *             单核的CPU表示只有一个大脑:
 *             不能够做到真正的多线程并发,但是可以做到给人一种“多线程并发”的感觉
 *             对于单核的CPU来说,在某一个时间点上实际上只能处理一件事情,但是由于
 *             CPU的处理速度极快,多个线程之间频繁切换执行,给人来的感觉是:多个事情同时在做!!!!!
 *             线程A:播放音乐
 *             线程B:运行魔兽游戏
 *             线程A和线程B频繁切换执行,人类会感觉音乐一直在播放,游戏一直在运行,给我们的感觉是同时并发的
 *
 *             电影院采用胶卷播放电影,一个胶卷一个胶卷播放速度达到一定程度之后,
 *             人类的眼睛产生了错觉,感觉是动画的,这说明人类的反应速度很慢,就像
 *             一根钢针扎到手上,到最终感觉到疼,这个过程是需要“很长的”时间的,在
 *             这个期间计算机可以进行亿万次的循环,所以计算机的执行速度很快
 *
 *         6、java语言中,实现线程有两种方式,哪两种方式呢?
 *             java支持多线程机制,并且java已经将多线程实现了,我们只需要继承就行
 *             第一种方式:编写一个类,直接继承java.lang.Thread,需要重写run方法
 *                         // 定义线程类
 *                             public class MyThread extends Thread{
 *                                 public void run(){
 *                                 }
 *                             }
 *                         // 创建线程对象
 *                                MyThread t = new MyThread();
 *                         // 启动线程
 *                                t.start();
 *
 *             第二种方式:编写一个类,实现java.lang.Runnable接口,实现run方法
 *                         // 定义一个可运行的类
 *                             public class MyRunnable implements Runnable {
 *                                 public void run(){
 *                                 }
 *                             }
 *                         // 创建线程对象
 *                             Thread t = new Thread(new MyRunnable());
 *                         // 启动线程
 *                             t.start();
 *                         注意:第二种方式实现接口比较常用,因为一个类实现了接口,它还可以去继承其它的类,更灵活
 *         7、怎么获取当前线程对象?
 *               static Thread currentThread();
 *            获取线程对象的名字
 *               String name=线程对象.getName();
 *            修改线程对象的名字
 *               线程对象.setName("线程名字");
 *
 *         8、关于线程对象的生命周期?
 *               新建状态
 *               就绪状态
 *               运行状态
 *               阻塞状态
 *               死亡状态
 *         9、了解——关于线程的调度
 * 	        9.1、常见的线程调度模型有哪些?
 *              抢占式调度模型:
 * 			        那个线程的优先级比较高,抢到的CPU时间片的概率就高一些/多一些
 * 			        java采用的就是抢占式调度模型
 * 		     均分式调度模型:
 * 			    平均分配CPU时间片,每个线程占有的CPU时间片时间长度一样
 * 			    平均分配,一切平等
 * 			    有一些编程语言,线程调度模型采用的是这种方式
 *
 *          9.2、java中提供了哪些方法是和线程调度有关系的呢?
 * 		    实例方法:
 * 			    void setPriority(int newPriority) 设置线程的优先级
 * 			    int getPriority() 获取线程优先级
 * 			    最低优先级1
 * 			    默认优先级是5
 * 			    最高优先级10
 * 			    优先级比较高的获取CPU时间片可能会多一些(但也不完全是,大概率是偏向优先级比较高的)
 * 		    静态方法:
 * 			    static void yield()  让位方法,暂停当前正在执行的线程对象,并执行其他线程
 * 			    yield()方法不是阻塞方法,让当前线程让位,让给其它线程使用
 * 			    yield()方法的执行会让当前线程从“运行状态”回到“就绪状态”
 * 			    注意:在回到就绪状态之后,有可能会再次抢到时间片
 * 		    实例方法:
 * 			    void join()————合并线程
 * 			    class MyThread1 extends Thread {
 * 				    public void doSome(){
 * 					    MyThread2 t = new MyThread2();
 * 					    t.join();      // 当前线程进入阻塞,t线程执行,直到t线程结束,当前线程才可以继续,两个栈之间发生了等待关系
 *                                }* 			}
 * 			    class MyThread2 extends Thread{
 * 			    }
*/
}

2.实现线程的第一种方式

主线程任务和分支线程任务演示

package com.java.javase.Thread;

public class ThreadTest01 {
    public static void main(String[] args) {
        MyThread myThread=new MyThread();
        
        myThread.start();
        for(int i=0;i<100;i++){
            System.out.println("主线程任务——"+i);
        }
    }
}
class MyThread extends Thread{                  // 继承Thread不能再继承别的类
    @Override
    public void run() {
        for(int i=0;i<100;i++){
            System.out.println("分支线程任务——"+i);
        }
    }
}

运行结果:

主线程任务——0
分支线程任务——0
主线程任务——1
分支线程任务——1
分支线程任务——2
分支线程任务——3
分支线程任务——4
分支线程任务——5
分支线程任务——6
分支线程任务——7
分支线程任务——8
分支线程任务——9
分支线程任务——10
分支线程任务——11
分支线程任务——12
分支线程任务——13
分支线程任务——14
分支线程任务——15
分支线程任务——16
分支线程任务——17
分支线程任务——18
分支线程任务——19
主线程任务——2
分支线程任务——20
主线程任务——3
分支线程任务——21
主线程任务——4

3.实现线程的第二种方式

package com.java.javase.Thread;

public class ThreadTest02 {
    public static void main(String[] args) {
    
        Thread t=new Thread(new Myrunnable());
        t.start();
        for(int i=0;i<100;i++){
            System.out.println("主线程——"+i);
        }
    }
}
class Myrunnable implements Runnable{
    @Override
    public void run() {
        for(int i=0;i<100;i++){
            System.out.println("分支线程——"+i);
        }
    }
}
package com.java.javase.Thread;
// 采用匿名内部类编写

public class ThreadTest03 {
    public static void main(String[] args) {
        Thread t=new Thread(new Runnable() {
            @Override
            public void run() {
                for(int i=0;i<100;i++){
                    System.out.println("分支线程——"+i);
                }
            }
        });
        t.start();
        for(int i=0;i<100;i++){
            System.out.println("主线程——"+i);
        }
    }
}

4.关于线程对象的名字

package com.java.javase.Thread;
// 1.获取当前线程对象
// 2.获取线程对象的名字
// 3.修改线程对象的名字

public class ThreadTest04 {
    public static void main(String[] args) {
        Thread currentThread=Thread.currentThread();
        // 获取主线程对象的名字
        System.out.println(currentThread.getName());
        MyThread t=new MyThread();
        // 设置线程对象的名字
        t.setName("tttt");
        // 获取线程对象的名字
        System.out.println(t.getName());
        // 启动线程
        t.start();
    }
}
class MyThread extends Thread{
    @Override
    public void run() {
        for(int i=0;i<100;i++){
            System.out.println("分支线程任务——"+i);
        }
    }
}

5.获取当前线程

Thread currentThread=Thread.currentThread();
System.out.println(currentThread.getName());

6.线程的sleep方法

package com.java.javase.Thread;

// 关于线程的sleep方法
// static void sleep(long millis) 抛出中断异常 InterruptedException
// 参数是毫秒
// 作用:让当前线程陷入休眠,进入“阻塞状态”,放弃占有的CPU时间片,让给其他线程使用
//     间隔特定的时间去执行特定的代码,每隔多久执行一次
// 这行代码出现在A线程中,A线程就会进入休眠状态
// 这行代码出现在B线程中,B线程就会进入休眠状态
public class ThreadTest05 {
    public static void main(String[] args) {
        try{
            Thread.sleep(1000*5);
        }catch(InterruptedException e){
            e.printStackTrace();
        }
        System.out.println("hello world!");
    }
}
package com.java.javase.Thread;

public class ThreadTest06 {
    public static void main(String[] args) {
        Thread t=new myThread();
        t.setName("java");
        t.start();
        try{
            t.sleep(1000*5);           // 在执行的时候还是会转换成Thread.sleep(1000*5);
        }catch(InterruptedException e){      // 这行代码的作用是:让当前线程进入休眠,也就是说main线程进入休眠
            e.printStackTrace();             // 这行代码出现在main方法中,main线程睡眠
        }
        System.out.println("hello world!");  // 5s之后输出
    }
}
class myThread extends Thread{
    public void run(){
        for(int i=0;i<10;i++){
            System.out.println(Thread.currentThread().getName()+"---"+i);
        }
    }

}

7.中断线程的睡眠

package com.java.javase.Thread;
// 怎么叫醒一个正在睡眠的线程,中断线程的睡眠?

public class ThreadTest07 {
    public static void main(String[] args) {
        Thread t=new Thread(new MyRunnable());
        t.start();
        try{
            Thread.sleep(1000*10);
        }catch(InterruptedException e){
            e.printStackTrace();
        }
        t.interrupt();
    }
}
class MyRunnable implements Runnable{
    // run()当中的异常不能throws,只能try catch
    // 因为run()方法在父类中没有抛出任何异常,子类不能比父类抛出更多的异常
    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName()+"---begin");
        try{
            Thread.sleep(1000*60*60*24);
        }catch(InterruptedException e){
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName()+"---over");
    }
}

8.stop方法—强行终止线程,直接将线程杀死,容易丢失数据

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

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

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