精华内容
下载资源
问答
  • 多线程概述

    2021-01-22 16:55:13
    多线程概述 多线程的创建方式 1、继承Thread类: 步骤:①、定义类继承Thread; ②、复写Thread类中的run方法; 目的:将自定义代码存储在run方法,让线程运行 ③、调用线程的start方法: · 该方法有两步:启动线程...

    多线程概述

    多线程的创建方式

    1、继承Thread类:

    步骤:①、定义类继承Thread;

    ②、复写Thread类中的run方法;

    目的:将自定义代码存储在run方法,让线程运行

    ③、调用线程的start方法:

    · 该方法有两步:启动线程,调用run方法。

    2、实现Runnable接口: 接口应该由那些打算通过某一线程执行其实例的类来实现。类必须定义一个称为run 的无参方法。

    实现步骤: ①、定义类实现Runnable接口

    ②、覆盖Runnable接口中的run方法

    将线程要运行的代码放在该run方法中。

    ③、通过Thread类建立线程对象。

    ④、将Runnable接口的子类对象作为实际参数传递给Thread类的构造函数。

    自定义的run方法所属的对象是Runnable接口的子类对象。所以要让线程执行指定对象的run方法就要先明确run方法所属对象

    ⑤、调用Thread类的start方法开启线程并调用Runnable接口子类的run方法。

    3、通过Callable和Future创建线程:

    实现步骤:①、创建Callable接口的实现类,并实现call()方法,改方法将作为线程执行体,且具有返回值。

    ②、创建Callable实现类的实例,使用FutrueTask类进行包装Callable对象,FutureTask对象封装了Callable对象的call()方法的返回值

    ③、使用FutureTask对象作为Thread对象启动新线程。

    ④、调用FutureTask对象的get()方法获取子线程执行结束后的返回值。

    通常,线程池都是通过线程池工厂创建,再调用线程池中的方法获取线程,再通过线程去执行任务方法。

    同步的前提:

    同步代码块中的锁对象可以是任意的对象;但多个线程时,要使用同一个锁对象才能够保证线程安全。

    同步方法中的锁对象是 this

    静态同步方法中的锁对象是 类名.class

    1、必须要有两个或者两个以上的线程。

    2、必须是多个线程使用同一个锁。

    3、必须保证同步中只能有一个线程在运行。

    4、只能同步方法,不能同步变量和类。

    5、不必同步类中所有方法,类可以拥有同步和非同步的方法。

    6、如果一个线程在对象上获得一个锁,就没有任何其他线程可以进入(该对象的)类中的任何一个同步方法。

    7、线程睡眠时,它所持的任何锁都不会释放。

    好处:解决了多线程的安全问题。

    弊端:多个线程需要判断,消耗资源,降低效率。

    注意:还可以通过Lock接口 new 实现类对象(Reentrantlock)创建锁

    等待唤醒机制

    线程之间的通信:多个线程在处理同一个资源,但是处理的动作(线程的任务)却不相同。通过一定的手段使各个线程能有效的利用资源。而这种手段即—— 等待唤醒机制。

    wait() :等待,将正在执行的线程释放其执行资格 和 执行权,并存储到线程池中。

    notify():唤醒,唤醒线程池中被wait()的线程,一次唤醒一个,而且是任意的。

    notifyAll(): 唤醒全部:可以将线程池中的所有wait() 线程都唤醒。

    唤醒的意思就是让 线程池中的线程具备执行资格

    代码示例

    public class Mytest {
        public static void main(String[] args) {
            /* 创建两个线程:一个线程打印 100个A,一个线程打印 100 个 B
          输出效果:ABABAB.....交替打印 */
            Print print = new Print();
            PrintA printA = new PrintA(print);
            PrintB printB = new PrintB(print);
            Thread thread1 = new Thread(printA);
            Thread thread2 = new Thread(printB);
            thread1.start();
            thread2.start();
        }
    }
    
    
    public class Print {
         boolean flag;
    }
    
    
    public class PrintA extends Thread{
    
        private Print object;
    
        public PrintA(Print object){
    
            this.object = object;
        }
    
        @Override
        public void run() {
            synchronized (object) {
                for (int i = 1; i <= 100; i++) {
                    if (object.flag!=false){
                        try {
                            object.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    System.out.print('A');
                    object.flag = true;
                    object.notify();
                }
            }
        }
    }
    
    
    public class PrintB extends Thread{
    
        private Print object;
    
        public PrintB(Print object){
            this.object = object;
        }
        @Override
        public void run() {
            synchronized (object) {
                for (int i = 1; i <= 100; i++) {
                    if (object.flag!=true) {
                        try {
                            object.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    System.out.print('B');
                    object.flag = false;
                    object.notify();
                }
            }
        }
    }
    
    展开全文
  • 多线程 多线程概述

    2017-12-13 22:33:12
    多线程概述 多线程的基本概念 进程可以理解成一个运行中的应用程序,是系统进行资源分配和调度的基本单位,是操作系统结构的基础,主要管理资源。 线程是进程的基本执行单元,一个进程对应多个线程。 主线程,处理...

    多线程概述

    多线程的基本概念

    进程可以理解成一个运行中的应用程序,是系统进行资源分配和调度的基本单位,是操作系统结构的基础,主要管理资源。 线程是进程的基本执行单元,一个进程对应多个线程。 主线程,处理UI,所有更新UI的操作都必须在主线程上执行。不要把耗时操作放在主线程,会卡界面。 多线程,在同一时刻,一个CPU只能处理1条线程,但CPU可以在多条线程之间快速的切换,按时间片轮转,由于切换时间够快,造成了多线程一同执行的假象。

    线程

    线程是进程内一个相对独立的,可调度的执行单元,是系统独立调度和分派CPU的基本单位。在单个程序中同时运行多个线程完成不同的工作,称为多线程。

    线程分为主线程和后台线程。 主线程贯穿程序运行的整个周期。主线程有时也被称为UI线程,因为好多UI相关的操作是在主线程里完成的。 后台线程需要手动创建。有自己的生命周期。 线程有优先级。 线程是一个被模拟出来的概念。CPU通过分配时间片模拟出多线程同时工作的状态。 运用多线程的目的是将耗时的操作放在后台执行。

    NSThread

    初始化:

    - (instancetype)initWithTarget:(id)target selector:(SEL)selector object:(nullable id)argument;
    复制代码

    启动:

    - (void)start;
    复制代码

    类方法:

    + (void)detachNewThreadSelector:(SEL)selector toTarget:(id)target withObject:(nullable id)argument;
    复制代码

    继承:

    @interface MyThread : NSThread
    @end
    
    @implementation MyThread
    - (void)main {
        ....;
    }
    复制代码

    线程状态

    新建 - 就绪- 运行 - 阻塞 - 死亡

    如何优雅的取消一个/结束一个线程

    + (void)exit;     // 只能作用于当前线程,一旦执行,立即终止,后续代码不会执行。之前申请的资源不会被释放,容易造成内存泄漏
    - (void)cancel;   // 不会直接取消线程,只是标记线程是被取消的状态
    复制代码

    NSThread API

    线程相关

    + (BOOL)isMainThread;
    + (NSThread *)mainThread;
    + (NSThread *)currentThread;
    复制代码

    暂停线程(阻塞)

    + (void)sleepUntilDate:(NSDate *)date;
    + (void)sleepForTimeInterval:(NSTimeInterval)ti;
    unsigned int sleep(unsigned int);
    复制代码

    线程通信

    @interface NSObject (NSThreadPerformAdditions)
    - (void)performSelectorOnMainThread:(SEL)aSelector withObject:(nullable id)arg waitUntilDone:(BOOL)wait;
    - (void)performSelectorInBackground:(SEL)aSelector withObject:(nullable is)argA;
    @end
    复制代码

    多线程的优缺点

    优点

    • 提高APP的实时响应性
    • 充分利用计算资源

    缺点

    • 额外的系统开销
    • 线程同步问题
    • 程序的复杂度上升

    线程开销

    项目 开销
    内核数据结构 1KB
    栈空间 主线程1MB,后台线程512KB(一张100*100的图片在内存里大约占40K)
    创建时间 90ms(16ms一帧,丢了6帧)

    线程同步

    int a = 0;
    thread1: a = a + 1;
    thread2: a = a + 2;
    result: a = ?
    may be 3,2or1;
    
    在多线程中,我们无法知道哪个线程先执行。
    复制代码

    NSLock

    int a = 0;
    
    thread1;
    加锁
    a = a + 1;
    解锁
    
    thread2;
    加锁
    a = a + 2;
    解锁
    复制代码

    @synchronized

    @synchronized (锁对象) {
        // 需要锁定的代码
    }
    复制代码

    比较synchronized和NSLock @synchronized使用简单。不会造成死锁。在@synchronized方法体中,如果发生异常,发法会进行解锁。而NSLock不会调用unlock。

    线程同步风险

    死锁

    总结

    多线程的基本概念 线程 NSThread 线程状态 NSThread API 多线程的优缺点

    展开全文
  • Java程序基础;多线程概述;多线程概述;线程与进程的比较;谢谢
  • 多线程概述二. 实现多线程的两种方式三. 多线程的生命周期四. 线程调度和控制一. 线程与进程的概述线程是依赖于进程而存在的,因此在讨论线程之前,我们必须要知道什么是进程1. 什么是进程进程就是正在运行的程序,...

    本文概述

    本篇文章将分四块内容对Java中的多线程机制进行介绍:

    一. 多线程概述

    二. 实现多线程的两种方式

    三. 多线程的生命周期

    四. 线程调度和控制

    一. 线程与进程的概述

    线程是依赖于进程而存在的,因此在讨论线程之前,我们必须要知道什么是进程

    1. 什么是进程

    进程就是正在运行的程序,是系统进行资源分配和调用的独立单位。每一个进程都有它自己的内存空间和系统资源。当我们打开电脑资源管理器时,就可以显示当前正在运行的所有进程。

    2. 多进程的意义

    大家应该有过这样的经历:我可以同时在电脑上做很多事情,比如我可以一边玩游戏,一边听音乐,网速够快我还可以同时用迅雷下载电影。这是因为我们的操作系统支持多进程,简而言之就是:能在同一时段内执行多个任务

    需要注意的是,对于单核计算机来讲,游戏和听音乐这两个任务并不是“同时进行”的,因为CPU在某个时间点上只能做一件事情,计算机是在游戏进程和音乐进程间做着频繁切换,且切换速度很快(也就是轮流执行CPU时间片),所以,我们感觉游戏和音乐好像在“同时”进行,其实并不是同时执行的。

    a9f59df76b65?utm_source=oschina-app

    CPU占用率  多进程的作用不是提高执行速度,而是提高CPU的使用率

    3. 什么是多线程

    在一个进程内部又可以执行多个任务,而这每一个任务我们就可以看成是一个线程。

    下面是一段代码示例:

    public class Demo {

    public static void main(String args[]) {

    //代码段1

    do();

    //代码段2

    }

    public static void do() {

    //代码段11

    function1();

    function2();

    //代码段22

    }

    public static void function1(){...}

    public static void function2(){...}

    }

    如果是单线程的执行方式:是一条执行路径

    a9f59df76b65?utm_source=oschina-app

    单线程方式.png

    如果是多线程的执行方式:有多条执行路径

    a9f59df76b65?utm_source=oschina-app

    多线程方式.png

    是进程中的单个顺序控制流,是一条执行路径。

    一个进程如果只有一条执行路径,则称为单线程程序。

    一个进程如果有多条执行路径,则称为多线程程序。

    4. 多进程的意义

    多线程的作用不是提高执行速度,而是为了提高应用程序的使用率。

    并行:逻辑上同时发生,指在某一段时间段同时运行多段程序

    并发:物理上同时发生,指在某一个时间点同时运行多段程序

    多线程却给了我们一个错觉:让我们认为多个线程是并发执行的。其实不是:多个线程共享同一个进程的资源,但是栈内存是独立的,一个线程一个栈。所以他们仍然是在抢CPU的资源执行。一个时间点上只有能有一个线程执行。而且谁抢到,这个不一定,所以,造成了线程运行的随机性。其中的某一个进程如果执行路径比较多的话,就会有更高的几率抢到CPU的执行权。

    5. Java中的多线程

    Java程序运行会启动JVM,相当于启动了一个进程,该进程会自动启动一个 “主线程” ,而main方法就运行在这个主线程当中,所以我们之前写的程序都是单线程。

    思考:JVM启动是单线程还是多线程?

    答案:多线程,JVM一定会启动主线程和垃圾处理机制,所以一定是多线程

    二. 实现多线程的两种方式

    1. 多线程实现方式V1.0(继承Thread类)

    根据API文档查询可以得到创建多线程的方法:

    自定义类继承Thread类

    该子类重写子类的run()方法

    并启动该子类的实例。

    调用实例的start方法

    放在run方法中的代码会被线程执行

    注意:run()方法实际上是单线程,不能直接调用run()方法,要先看到多线程的效果,必须使用start()方法。run()仅仅只是被封装的执行代码,而是普通方法,然而start方法会先启用线程,然后再用jvm去调用线程的run方法

    因此:要启动多线程,一定要调用start()方法,不能使用run()方法

    子线程1(Thread1):

    public class FirstThread extends Thread{

    public void run() {

    for(int i = 0; i < 100; i++) {

    System.out.println("Thread1\t" + i);

    }

    }

    }

    子线程2(Thread2):

    public class SecondThread extends Thread{

    public void run() {

    for(int i = 0; i < 100; i++) {

    System.out.println("Thread2\t" + i);

    }

    }

    }

    main函数

    public class MyThreadDemo {

    public static void main(String args[]) {

    Thread t1 = new FirstThread();

    Thread t2 = new SecondThread();

    t1.start();

    t2.start();

    }

    }

    2. 多线程实现方式V2.0(实现Runnable接口)

    自定义类MyRunnerble()实现Runnable接口

    在MyRunnerble中重写run()方法

    创建MyRunnerble的实例对象

    将所创建的对象作为参数传入到Thread当中

    public class MyThreadDemo2 {

    public static void main(String args[]) {

    Thread t1 = new Thread(new Runnable() {

    @Override

    public void run() {

    for(int i = 0; i < 100; i++) {

    System.out.println("thread1" + i);

    }

    }

    });

    Thread t2 = new Thread(new Runnable() {

    @Override

    public void run() {

    for(int i = 0;i < 100; i++) {

    System.out.println("thread2" + i);

    }

    }

    });

    t1.start();

    t2.start();

    }

    }

    3. 两种创建方式的比较

    既然有了方式一,为什么又要有方式二呢?

    比较两种创建方式,我们不难发现,第一种方式是通过继承的方式实现的,第二种方式是通过接口的方式实现。

    继承Runnerble接口的优点:

    1. 可以避免Java单继承带来的局限性。

    2. 适合多个相同程序的代码去处理同一个资源的情况,把线程同程序的代码,数据有效的分离,较好体现了面向对象的设计思想。

    三. 多线程的生命周期

    多线程的生命周期如下图所示:

    a9f59df76b65?utm_source=oschina-app

    线程生命周期图.png

    四. 线程调度和控制

    1. 线程调度

    如果我们的计算机只有一个 CPU,那么 CPU 在某一个时刻只能执行一条指令,线程只有得到 CPU时间片,也就是使用权,才可以执行指令。那么Java是如何对线程进行调用的呢?

    线程调度的两种模式

    分时调度模式:所有线程轮流使用 CPU 的使用权,平均分配每个线程占用 CPU 的时间片。

    抢占式调度模型:优先让优先级高的线程使用 CPU,如果线程的优先级相同,那么会随机选择一个,优先级高的线程获取的 CPU 时间片相对多一些。

    Java采用的是抢占式调度模式,用优先级控制时间片轮转。

    设置和获取优先级的方式如下:

    public final int getPriority()

    public final void setPriority(int newPriority)

    2. 线程的控制

    2.1 线程休眠

    相当于在线程中暂停了几秒

    方法:

    public static void sleep(long millis)

    示例

    public class SecondThread extends Thread{

    public void run() {

    try {

    Thread.sleep(1000);

    } catch (InterruptedException e) {

    e.printStackTrace();

    }

    System.out.println("线程2");

    }

    }

    注意

    该方法是静态方法,可以通过类直接调用,而且会抛出异常。

    2.2 线程加入

    为了让某些需要执行的线程执行完毕,别的线程才能拿够继续

    方法

    public final void join()

    示例

    public class MyThreadDemo {

    public static void main(String args[]) {

    Thread t1 = new FirstThread();

    Thread t2 = new SecondThread();

    t1.start();

    try {

    t1.join();

    } catch (InterruptedException e) {

    e.printStackTrace();

    }

    t2.start();

    }

    }

    注意

    只有当t1线程执行完毕之后才会执行第二个线程,要注意该方法也会抛出异常。

    2.3 线程礼让

    暂停执行当前线程,并执行其他线程,在一定的程度上能够交替执行,但不能保证一定是交替执行的

    方法

    public static void yield()

    注意

    使用方法与之前类似,该方法是静态方法,所以直接可以通过类调用

    2.4 后台线程(守护线程)

    将该线程标记为守护线程或者是用户线程,当正在运行的线程都是守护线程时,java虚拟机退出。

    方法

    public final void setDaemon(boolean on)

    示例:

    public class MyThreadDemo {

    public static void main(String args[]) {

    Thread t1 = new FirstThread();

    Thread t2 = new SecondThread();

    Thread t3 = new ThirdThread();

    t1.setDaemon(true);//将t1设置为守护进程

    t2.setDaemon(true);//将t2设置为守护进程

    t1.start();

    t2.start();

    t3.start();

    }

    }

    注意:

    该方法只能够在开启线程之前使用,而且不能立即停止,有一定的延迟。

    2.5 线程中断

    中途关闭线程

    方法

    public final void stop()//过时了,但是还是可以使用的,不安全不建议使用

    public void interrupt()//他让我们抛出一个异常,如果受阻,那么状态终止,抛出异常

    总结

    多线程是Java各种机制中非常重要也是比较陌生的一块内容,需要对计算机操作系统运行机制有一定了解的情况下才能深入理解,之后的文章会对多线程的安全,死锁和与线程有关的设计模式做更深入的介绍,欢迎继续观看后续内容,一起体会Java语言的智慧与魅力。

    展开全文
  • 第一章 Java多线程概述线程的启动线程的暂停线程的优先级线程安全相关问题1.1 进程与线程进程:可以将运行在内存中的程序(如exe文件)理解为进程,进程是受操作系统管理的基本的运行单元。线程:可以理解为进程中...

    第一章 Java多线程概述

    • 线程的启动

    • 线程的暂停

    • 线程的优先级

    • 线程安全相关问题

    1.1 进程与线程

    进程:可以将运行在内存中的程序(如exe文件)理解为进程,进程是受操作系统管理的基本的运行单元。

    线程:可以理解为进程中独立运行的子任务。如果QQ.exe运行时的好友视频线程、下载文件线程、数据传输线程、发送消息线程等。

    使用多线程可以更好的利用计算机的资源如CPU。线程被调用的时机是随机的。

    1.2 Java多线程实现方式

    1.2.1 继承Thread类

    public class Thread implement Runnable

    Thread 类实现了Runnable接口,它们之间具有多态关系。重新run方法,方法内编写执行任务的代码。启动线程后会调用run方法。当run方法执行结束后,线程也会跟着终止。

    我们需要在主程序中使用Thread类的start方法启动新的线程。

      public class MyThread extends Thread{ 
    @override
    public void run(){    
            System.out.println("新的线程!");    
    }
    }
    public class Main{
    public static void main(String[] args){
        MyThread t = new MyThread();
          t.start();
          System.out.println("主线程!");
    }
    }

    注:多次调用start方法会出现IllegalThreadStateException异常。

    1.2.2 实现Runnable接口

    继承Thread实现多线程有设计上的局限性,如果欲创建的线程类已经有一个父类,这是不能再继承Thread类了,java不支持多继承,所以可以实现Runnable接口。

      public class MyRunnable implements Runnable {
    @override
    public void run(){
        System.out.println("运行中");
    }
    }

    Thread类有两个构造器函数Thread(Runnable target)和Thread(Runnable target, String name)可以接收Runnable接口。

      public class Main{
    public static void main(String[] args){
    Runnable r = new MyRunnable();
        Thread t = new Thread(r);
          t.start();
          System.out.println("主线程!");
    }
    }

    1.2.3 ThreadFactory启动线程

    java.util.concurrent中包含一个将线程创建抽象化的ThreadFactory接口。利用该接口,可以将Runnable作为参数并通过new创建Thread实例的处理隐藏在ThreadFactory内部。默认的ThreadFactory对象是通过Executor.defaultThreadFactoy方法获取的。

      public class Main{
    public static void main(String[] args){
    ThreadFactory factory = Executor.defaultThreadFactoy;
    Runnable r = new MyRunnable();
        factory.newThread(MyRunnable).start();    
    }
    }

    1.3 线程安全与锁

    在共享数据的情况下即多个线程访问同一变量,可能存在线程安全问题。

    通过在run方法前加入synchronized关键字,使得多个线程在执行run方法时排队进行处理。

    synchronized可以在任意对象及方法上加上锁,加锁的到吗称为“互斥区”或“临界区”。

      public class MyThread extends Thread{ 
    private int count = 5;
    @override
    synchronized public void run(){        
            count--;
    }
    }

    synchronized方法和synchronized代码块

      synchronized void method(){
    ...
    }
    void method(){
    synchronized(this){
        ...
    }
    }

    死锁:两个线程分别持有锁,并互相等待对方释放锁。

    发生死锁的条件:

    (1)存在多个sharedResource角色;

    (2)线程持有某个SharedRosource角色锁的同时,还想获取其他SharedResource角色的锁;

    (3)获取SharedResource角色的锁的顺序并不固定

    1.4 停止线程

    停止一个线程意味着在线程处理完任务之前停掉正在做的操作。虽然看起来非常简单,但是必须做好防范,以便达到预期的效果。停止一个线程可以使用Thread.stop()方法,但是最好不用它,已经被java高版本放弃。

    大多数停止一个线程的操作使用Thread.interrupt()方法。

    Java中三种停止正在运行线程的方法:

    • 设置退出标志变量,也就是当run方法完成后线程终止;

    • 使用stop方法,但不推荐;

    • 使用interrupt方法中断线程。

    interrupt方法仅仅是在当前线程中打了一个停止标记,并不是真的停止线程。

    • this.interrupted():测试当前线程是否已经中断,执行后具有将状态标志清除为false的功能;

    • this.isInterrupted():线程线程Thread对象是否已经中断状态,但不清楚状态标志。

    如果在sleep状态下停止一个线程,会进入catch语句,并且清楚停止状态值,使之变成false。

    如果使用stop强制让线程停止则有可能使一些请理性的工作得不到完成。另外就是对锁定对象进行了解锁,导致数据得不到同步处理,出现数据不一致问题。

    1.5 暂停线程

    暂停线程意味着线程还可以恢复运行。java中使用suspend方法暂停线程,使用resume方法恢复线性。

    使用suspend和resume方法如果使用不当,极易造成公共的同步对象的独占,使得其他线程无法访问公共同步对象。

    同时也容易出现数据不同步情况。

    1.5 Thread相关方法

    • Thread.currentThread()方法可以返回当前线程信息,如Thread.currentThread().getName();

    • getId():获取线程唯一标识

    • sleep(long millis):将正在执行的线程休眠。

      sleep方法使当前线程(即调用该方法的线程)暂停执行一段时间,让其他线程有机会继续执行,但它并不释放对象锁。也就是说如果有synchronized同步快,其他线程仍然不能访问共享数据。注意该方法要捕捉异常。sleep()可以使低优先级的线程得到执行的机会,当然也可以让同优先级、高优先级的线程有执行的机会。

    • yield():方法的作用是放弃当前CPU资源,将它让给其他的任务去占用CPU执行时间。

      一个调用yield()方法的线程告诉虚拟机它乐意让其他线程占用自己的位置。这表明该线程没有在做一些紧急的事情。注意,这仅是一个暗示,并不能保证不会产生任何影响。并且yield方法只能让同优先级的线程有执行的机会。

    • wait()和notify()、notifyAll() :都是java.lang.Object的方法

      这三个方法用于协调多个线程对共享数据的存取,所以必须在synchronized语句块内使用。synchronized关键字用于保护共享数据,阻止其他线程对共享数据的存取,但是这样程序的流程就很不灵活了,如何才能在当前线程还没退出synchronized数据块时让其他线程也有机会访问共享数据呢?此时就用这三个方法来灵活控制。

      wait()方法使当前线程暂停执行并释放对象锁标示,让其他线程可以进入synchronized数据块,当前线程被放入对象等待池中。当调用notify()方法后,将从对象的等待池中移走一个任意的线程并放到锁标志等待池中,只有锁标志等待池中线程能够获取锁标志;如果锁标志等待池中没有线程,则notify()不起作用。

      notifyAll()则从对象等待池中移走所有等待那个对象的线程并放到锁标志等待池中。

    1.6 线程优先级

    在操作系统中,线程可以划分优先级,优先级较高的线程的到CPU资源较多。

    优先级的继承特性:如果A线程启动B线性,则AB优先级一样。

    使用setPriority()可以设置优先级:java提供了三个变量MIN_PRIORITY、MAX_PRIORITY和NORM_PRIORITY

    优先级较高的线程不一定每次都先执行完。

    1.7 守护线程

    java线程中有两种线程,一种是用户线程,另一种是守护线程。

    当进程中不存在非守护线程了,则守护线程自动销毁。典型的守护线性就是垃圾回收线程。

    转载于:https://www.cnblogs.com/zhuweiheng/p/10465934.html

    展开全文
  • 第1章多线程概述 学习多线程之前,我们先要了解几个关于多线程有关的概念。 A:进程:进程指正在运行的程序。确切的来说,当一个程序进入内存运行,即变成一个进程,进程是处于运行过程中的程序,并且具有一定独立...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 10,775
精华内容 4,310
关键字:

多线程概述