Java多线程编程核心技术的笔记之1

极客导航  2018-05-27 15:34  阅读 88 次 评论 0 条

1、什么是进程,线程和多线程

1. 进程

在百度百科中的定义是

进程(process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础.程序是指令,数据以及组织形式的描述,进程是程序的实体.

我们可以把win系统中运行的一个exe程序看做一个进程,Android中可以把一个应用看做一个进程.

2.线程

在百度百科中的定义是

线程,有时被称为轻量级进程(Lightweight Process,LWP),是程序执行流的最小单元。线程是进程中的一个实体,是被系统独立调度和分派的基本单位,线程自己不拥有系统资源,只拥有一点儿在运行中必不可少的资源,但它可与同属一个进程的其它线程共享进程所拥有的全部资源。

线程可以理解为在进程中独立运行的子任务.比如腾讯QQ.exe运行时,有很多子任务在执行,文件传输任务,视频直播任务,文档下载任务等.这些子任务都是线程.

PS:多线程是异步的,线程被调用是随机的.

3. 多线程

在百度百科中的定义是

多线程(英语:multithreading),是指从软件或者硬件上实现多个线程并发执行的技术。

好处:提供执行效率或性能

多线程就是我们在用QQ聊天时,可以一边下载文件,一遍视频直播等"同时"操作.

2、线程的实现和启动

1.继承Thread


    //匿名启动
    new MyThread().start();

    //
    MyThread myThread = new MyThread();
    //不能调用多次
    myThread.start();


    private class MyThread extends Thread {
        @Override
        public void run() {
            super.run();
        }
    }

PS:一个线程变量不能多次调用start(),否则会出现:Exception in thread "main" java.lang.IlleaglThreadStateException异常.

2.实现Runnable接口

    //通过Thread启动
    Thread thread= new Thread(new MyRunnable());
    thread.start();
        
    //实现Runnable接口
    private class MyRunnable implements Runnable{

        @Override
        public void run() {

        }
    }

由于Java是单继承,不允许多继承,因此继承Thread有一定的局限性,推荐大家使用第二种方式

3、什么是非线程安全

非线程安全主要是指:多个线程对同一个对象中的同一个实例变量进行操作时会出现值被更改和值不同步的情况,进而影响程序执行流程.

解决发生非线程安全问题的方法就是使用同步方法等同步手段

4、线程中的一些方法

1. start()

启动线程,但此时线程只是处于就绪状态,并没有执行.至于什么时候执行需要看CPU.

2. currentThread()

返回当前代码是在哪个线程中调用.

3.isAlive()

判断当前线程是否处于线程已经启动且尚未终止的活动状态

4. sleep()

指定休眠一段时间,但此时不会释放锁,休眠后继续运行.

5. getId()

获取线程的唯一标识ID

6. interrupt()

在当前线程中设置一个中断标志,并不会直接中断线程.

7.interrupted()

测试当前线程是否中断状态,执行后同时将状态标志设置为false

8. isInterrupted()

判断线程Thread对象是否是中断状态,但不清除状态标志.

9. yield()

放弃当前的CPU资源,将它让给其他的任务占用CPU资源,当放弃的时间不确定,有可能当放弃,又重新获取CPU时间.

5、停止线程

停止线程单独提出了,因为这有些'麻烦'

一下三种可以终止正在运行的线程:

1. 使用退出标志,使线程正常退出.也就是当run()方法完成后线程终止

2. 使用stop()方法强行终止线程,,,但stop()方法已经废弃,不推荐使用

3. 使用interrup()方法中断线程.

方法1:使用线程中断标志判断线程是否退出状态

从上面第4部分我们知道.interrupt()方法是中断线程的,但又不是真真的"中断",只是把线程中断标志设置位true.

            //中断当前线程
             Thread.currentThread().interrupt();

            //获取中断标志位
            Log.d(TAG, "---1--interrupted:"+ Thread.interrupted()); //true
            Log.d(TAG, "---2--interrupted:"+ Thread.interrupted()); //false
        MyThread myThread = new MyThread();
        myThread.start();
        //中断myThread线程
        myThread.interrupt();
        Log.d(TAG, "---1--interrupted:" + myThread.isInterrupted()); //true
        Log.d(TAG, "---2--interrupted:" + myThread.isInterrupted()); //true

我们可以通过线程的静态方法interrupted()方法获取当前线程的中断标志并返回,但我们要记住,interrupted()方法调用后会把中断标志清除并设置为false

而非静态方法isInterrupted()方法返回调用的线程是否中断,调用后也不会把中断状态清除.

因此我们可以在线程中,如果需要退出,通过判断中断标志然后退出

        try {
            //线程的启动
            MyThread myThread = new MyThread();
            myThread.start();

            //延迟2s
            Thread.sleep(2000);

            //myThread设置中断
            myThread.interrupt();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    //定义一个线程
    private class MyThread extends Thread {
        @Override
        public void run() {
            super.run();
            try {
                Log.d(TAG, "-------for---start------");
                for (int i = 0; i < 10; i++) {
                    Log.d(TAG, "------current i:" + i);
                    Thread.sleep(1000);
                    if(this.interrupted()){
                        //如果有中断(true),抛出中InterruptedException
                        throw new InterruptedException();
                    }
                }
                Log.d(TAG, "-------for---end------");
            } catch (InterruptedException e) {
                Log.d(TAG, "-----catch" +
                        "" +
                        "-InterruptedException------");
                e.printStackTrace();
            }

            Log.d(TAG, "-------run---end------");
        }
    }

打印日志

-------for---start------
------current i:0
------current i:1
-----catch-InterruptedException------
-------run---end------

......

后续整理,这部分有些不太懂.....谢谢理解

6、线程的优先级

在操作系统中,线程是划分优先级的.优先级高的线程得到的CPU资源最多,也就是CPU优先执行优先级高的线程对象.

在Java中,线程的优先级划分为1~10个等级,如果大于10或者小于0,JDK会抛出异常throw new IllegalArgumentException

Java中定义了三个优先级常量:

public final static int MIN_PRIORITY = 1;
public final static int NORM_PRIORITY = 5;
public final static int MAX_PRIORITY = 10;

在Java中,线程的优先级是具有继承性的和随机性的.线程A中启动线程B,那么线程A和线程B的优先级都是一样的.如果线程C的优先级比线程D高,但执行结果并不是一定先执行玩C再执行D的.

PS:优先级高的线程并不是一定先执行完,而是CUP尽可能的把资源让给优先级高的线程对象.

7、守护线程

Java中有两种线程,一种是用户线程,另一种是守护线程.

守护线程就是一种特殊的线程,它具有陪伴的特性.

当进程中没有用户进程时候,守护线程就会自动销毁.

典型的守护线程有垃圾回收线程.如果用户线程不存在,垃圾线程也就没必须要存在,所以会自动销毁.

本文地址: https://www.125la.com/337.html
关注我们:请关注一下我们站长微信:扫描二维码125啦读书导航的微信号,微信号:yudemi(十三少)
版权声明:本文为原创或转载文章,版权归原作者所有,欢迎分享本文,转载请保留出处!
第一个读书导航

发表评论


表情