精华内容
下载资源
问答
  • 【多线程并发编程】 线程的礼让守护线程

    千次阅读 多人点赞 2020-02-27 01:27:52
    线程的礼让yield守护线程,我们日常的开发中,都不会用到,为什么还需要了解他?

    程序猿学社的GitHub,欢迎Star
    https://github.com/ITfqyd/cxyxs
    本文已记录到github,形成对应专题。

    前言

    上一篇文章,我们了解线程的优先级,这次,我们一起来学习一下线程的礼让和守护。听起来是不是一脸懵逼,别急,我们来一一了解。

    1.线程的礼让

    什么是线程的礼让

    线程的礼让,就是让出自己抢到的执行权,也就是我们所说的时间片,让出执行权,并不意味着,该线程不参与下轮的争抢勒。

    yield方法

    打开Thread类,通过alt+7(idea版本),我们可以快速找到该方法。

      public static native void yield();
    
    • 我们可以看到有一个关键字native,但是,我们找不到具体的方法,说明他是通过C或者C++实现的,使用native关键字说明这个方法是原生函数。
    • 如果用使用过java调用dll文件的社友,就会觉得这个很熟悉,熟悉的味道。

    为什么不通过java实现?

    • 我们查看jdk源码,可以发现有不少方法被修饰为native,Java 1.1开始就引入了JNI,如果我们想与操作系统进行交互,就需要通过JNI与操作系统进行交互。

    yield实战

    package com.cxyxs.thread.eight;
    
    /**
     * Description:转发请注明来源  程序猿学社 - https://ithub.blog.csdn.net/
     * Author: 程序猿学社
     * Date:  2020/2/26 19:05
     * Modified By:
     */
    public class YieldThread  implements  Runnable{
        @Override
        public void run() {
            System.out.println(Thread.currentThread().getName()+",早上打卡上班");
            Thread.yield();
            System.out.println(Thread.currentThread().getName()+",晚上打卡下班");
        }
    
        public static void main(String[] args) {
            YieldThread yieldThread = new YieldThread();
            Thread t = new Thread(yieldThread,"程序猿学社");
            Thread t1 = new Thread(yieldThread,"隔壁老王");
            t.start();
            t1.start();
        }
    }
    
    

    交替运行
    在这里插入图片描述
    先运行玩完一个线程,再运行另外一个线程。在这里插入图片描述

    • 通过多次测试,我们可以得出一个结论。调用yield方法会使线程让出当前的执行权,但是,并不代表,他不参与下轮的时间片的争抢。
    • 调用该方法会使线程从运行状态切换到就绪状态。
    • 下一次再拿到时间片后,会继续从调用yield方法后的下一句代码开始运行。
      在这里插入图片描述

    2.守护线程

    守护线程的概念

    java线程可以划分为两种:

    • 用户线程(我们自定义的线程)
    • 守护线程(就是为他人服务的,当java进程中没有用户线程时,他就会自动销毁),我们常见的有垃圾回收线程。
      案例:
      守护线程可以理解为玄幻小说里面的宠物,跟主人签订了主从协议,主人身死,自己也会死掉。

    守护线程场景

    • 我们的垃圾回收线程就是一个守护线程,为什么要设计成守护线程,他就是为了保证,所有的用户线程都退出后,直接不产生新的垃圾后,作为我们java的雷锋同志垃圾回收线程,才会默默地消失。
      在这里插入图片描述
    • 通过查看Timer定时器的源码,我们可以发现,他竟然可以传参数设置是否为守护线程。

    代码实战

    package com.cxyxs.thread.eight;
    
    /**
     * Description:守护线程
     * 转发请注明来源  程序猿学社 - https://ithub.blog.csdn.net/
     * Author: 程序猿学社
     * Date:  2020/2/27 0:31
     * Modified By:
     */
    public class WatchThread implements  Runnable{
        @Override
        public void run() {
            for (int i = 0; i < 1000; i++) {
                try {
                    System.out.println("程序猿学社:第"+i+"次打卡");
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    
        public static void main(String[] args) {
            WatchThread watchThread = new WatchThread();
            Thread thread = new Thread(watchThread);
            thread.setDaemon(true);  //设置线程为守护线程
            thread.start();
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("main线程已结束!");
        }
    }
    

    在这里插入图片描述

    • 不设置setDaemon,通过Thread源码,可以发现默认值为false,也就是说,我们自定义的线程,如果再不手动设置为true的前提下,自定义的线程都是用户线程。
    • 通过测试,我们可以发现main线程已经打印结束的情况下,从线程还在运行。一直在不停的打印。
    • main线程是用户线程,不是守护线程,这里验证完毕,有不少社友认为main线程是守护线程。
      在这里插入图片描述
    • setDaemon方法为true,表示设置为守护线程。
    • 在没有用户线程的情况下,进程会自动退出。其他的守护线程也会自动销毁。

    验证线程是否为守护线程

    package com.cxyxs.thread.eight;
    
    /**
     * Description:转发请注明来源  程序猿学社 - https://ithub.blog.csdn.net/
     * Author: 程序猿学社
     * Date:  2020/2/27 1:11
     * Modified By:
     */
    public class Demo1 {
        public static void main(String[] args) {
            System.out.println(Thread.currentThread().getName()+"线程");
            System.out.println(Thread.currentThread().isDaemon());
        }
    }
    

    在这里插入图片描述

    • 通过这个案例,我们应该知道main线程不是守护线程了把。

    总结:实际上,在我们日常的开发过程中,几乎都不会用到线程的礼让和守护线程。但是,我们为什么需要去了解他。这种问题,就类似于我们学习springboot是否还需要学习springmvc一样。个人觉得,底层原理还是有学习的必要,这样你才能知其然知其所以然,而不是永远停用在使用的阶段,这也是我们大部分的开发,工作几年后,工资一直上不去的原因。

    展开全文
  • CPU四核八线程和四核四线程的区别

    千次阅读 2020-10-30 10:01:24
    四个人每人在用一只手工作 四个人每人在用两只手工作 大概就是这个区别 https://zhidao.baidu.com/question/871291752790331852.html

    四个人每人在用一只手工作 四个人每人在用两只手工作
    大概就是这个区别

    https://zhidao.baidu.com/question/871291752790331852.html

    展开全文
  • } } 执行结果如下: 一、守护线程 线程分为用户线程和守护线程 虚拟机必须确保用户线程执行完毕 虚拟机不用等待守护线程执行完毕 如,后台记录操作日志,监控内存,垃圾回收等待。。。 代码案例 public class ...
    一、线程的状态
    • new 尚未启动的线程处于此状态

    • Runnable 在java虚拟机中执行的线程处于此状态

    • Blocked 被阻塞等待监视器锁定的线程处于此状态。

    • Waiting 正在等待另一个线程执行特定动作的线程处于此状态。

    • Timed Waiting 正在等待另一个线程执行动作达到指定等待时间的线程处于此状态。

    • Terminated 已退出的线程处于此状态。

    • 代码案例

    /**
     * 线程的状态
     */
    public class TestThreadStatus{
    
        public static void main(String[] args) throws InterruptedException {
            //我们用lamda表达式来启动一个线程
            Thread th = new Thread(()->{
                for (int i = 0; i <5 ; i++) {
                    try {
                        Thread.sleep(100);
    
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.println("");
            });
    
            Thread.State state = th.getState();
            System.out.println("创建时线程的状态+"+state);//线程的状态
    
            th.start();//启动线程
            state = th.getState();
            System.out.println("启动时线程的状态+"+state);
    
            //只要线程不终止就输入线程状态
            while (state != Thread.State.TERMINATED){
                Thread.sleep(100);
                state = th.getState();
                System.out.println("new+"+state);
            }
    
    
    
        }
    
    }
    
    
    • 执行结果如下:
      在这里插入图片描述
    一、线程的优先级
    • java提供一个线程调度器来监控程序中启动后进入就绪状态的所有线程,线程调度器按照优先级决定应该调度哪个线程来执行。

    • 线程的优先级用数字表示,范围从1~10。

    • 使用以下方式改变或获取优先级

      • getPriority().setPriority(int xxx)
    • 代码案例:

    /**
     * 线程优先级,不一定成功
     */
    public class TestThreadPriority {
        public static void main(String[] args) {
            MyPriority myPriority = new MyPriority();
            Thread t1 = new Thread(myPriority);
            Thread t2 = new Thread(myPriority);
            Thread t3 = new Thread(myPriority);
            Thread t4 = new Thread(myPriority);
            Thread t5 = new Thread(myPriority);
            Thread t6 = new Thread(myPriority);
            //先设置线程优先级
            t1.setPriority(1);
            t1.start();
            t2.setPriority(3);
            t2.start();
            t3.setPriority(6);
            t3.start();
            t4.setPriority(Thread.MAX_PRIORITY);//  优先级=10
            t4.start();
            t5.setPriority(Thread.MIN_PRIORITY);// 优先级=1
            t6.setPriority(9);
            t6.start();
    
            System.out.println("main");
        }
    }
    
    class MyPriority implements Runnable{
    
        @Override
        public void run() {
            System.out.println(Thread.currentThread().getName()+"---线程被执行了!---"+Thread.currentThread().getPriority());
        }
    }
    
    • 执行结果如下:
      在这里插入图片描述
    一、守护线程
    • 线程分为用户线程和守护线程

    • 虚拟机必须确保用户线程执行完毕

    • 虚拟机不用等待守护线程执行完毕

      • 如,后台记录操作日志,监控内存,垃圾回收等待。。。
    • 代码案例

    public class TestDaemon {
        public static void main(String[] args) {
            God god = new God();
            You you=new You();
            Thread thread = new Thread(god);
            thread.setDaemon(true);//默认为flase 为用户线程,  true为守护线程
            thread.start();
            new Thread(you).start();
        }
    }
    class God implements Runnable{
    
        @Override
        public void run() {
            while (true){
                System.out.println("上帝守护着你-------");
            }
        }
    }
    class You implements Runnable{
    
        @Override
        public void run() {
            for (int i = 0; i <36500 ; i++) {
                System.out.println("开心着活着每一天------");
            }
            System.out.println("----goodbye!Beautiful World!!!------");
    
        }
    }
    
    • 执行结果如下:

    在这里插入图片描述
    路漫漫其修远兮,吾必将上下求索~
    如果你认为i博主写的不错!写作不易,请点赞、关注、评论给博主一个鼓励吧**转载请注明出处哦**

    Java多线程扩展:Java多线程学习汇总

    展开全文
  • 秒杀多线程篇 经典线程同步 信号量Semaphore

    万次阅读 多人点赞 2012-05-03 09:30:00
    阅读本篇之前推荐阅读以下姊妹篇:《秒杀多线程第四篇一个经典的多线程同步问题》《秒杀多线程第五篇经典线程同步关键段CS》《秒杀多线程第六篇经典线程同步事件Event》《秒杀多线程第七篇经典线程同步互斥量Mutex》...

    阅读本篇之前推荐阅读以下姊妹篇:

    秒杀多线程第四篇一个经典的多线程同步问题

    秒杀多线程第五篇经典线程同步关键段CS

    秒杀多线程第六篇经典线程同步事件Event

    秒杀多线程第七篇经典线程同步互斥量Mutex

     

    前面介绍了关键段CS事件Event互斥量Mutex在经典线程同步问题中的使用。本篇介绍用信号量Semaphore来解决这个问题。

    首先也来看看如何使用信号量,信号量Semaphore常用有三个函数,使用很方便。下面是这几个函数的原型和使用说明。

    第一个 CreateSemaphore

    函数功能:创建信号量

    函数原型:

    HANDLE CreateSemaphore(

      LPSECURITY_ATTRIBUTES lpSemaphoreAttributes,

      LONG lInitialCount,

      LONG lMaximumCount,

      LPCTSTR lpName

    );

    函数说明:

    第一个参数表示安全控制,一般直接传入NULL

    第二个参数表示初始资源数量。

    第三个参数表示最大并发数量。

    第四个参数表示信号量的名称,传入NULL表示匿名信号量。

     

    第二个 OpenSemaphore

    函数功能:打开信号量

    函数原型:

    HANDLE OpenSemaphore(

      DWORD dwDesiredAccess,

      BOOL bInheritHandle,

      LPCTSTR lpName

    );

    函数说明:

    第一个参数表示访问权限,对一般传入SEMAPHORE_ALL_ACCESS。详细解释可以查看MSDN文档。

    第二个参数表示信号量句柄继承性,一般传入TRUE即可。

    第三个参数表示名称,不同进程中的各线程可以通过名称来确保它们访问同一个信号量。

     

    第三个 ReleaseSemaphore

    函数功能:递增信号量的当前资源计数

    函数原型:

    BOOL ReleaseSemaphore(

      HANDLE hSemaphore,

      LONG lReleaseCount,  

      LPLONG lpPreviousCount 

    );

    函数说明:

    第一个参数是信号量的句柄。

    第二个参数表示增加个数,必须大于0且不超过最大资源数量。

    第三个参数可以用来传出先前的资源计数,设为NULL表示不需要传出。

     

    注意:当前资源数量大于0,表示信号量处于触发,等于0表示资源已经耗尽故信号量处于末触发。在对信号量调用等待函数时,等待函数会检查信号量的当前资源计数,如果大于0(即信号量处于触发状态),减1后返回让调用线程继续执行。一个线程可以多次调用等待函数来减小信号量。 

     

    最后一个 信号量的清理与销毁

    由于信号量是内核对象,因此使用CloseHandle()就可以完成清理与销毁了。

     

    在经典多线程问题中设置一个信号量和一个关键段。用信号量处理主线程与子线程的同步,用关键段来处理各子线程间的互斥。详见代码:

    #include <stdio.h>
    #include <process.h>
    #include <windows.h>
    long g_nNum;
    unsigned int __stdcall Fun(void *pPM);
    const int THREAD_NUM = 10;
    //信号量与关键段
    HANDLE            g_hThreadParameter;
    CRITICAL_SECTION  g_csThreadCode;
    int main()
    {
    	printf("     经典线程同步 信号量Semaphore\n");
    	printf(" -- by MoreWindows( http://blog.csdn.net/MoreWindows ) --\n\n");
    
    	//初始化信号量和关键段
    	g_hThreadParameter = CreateSemaphore(NULL, 0, 1, NULL);//当前0个资源,最大允许1个同时访问
    	InitializeCriticalSection(&g_csThreadCode);
    
    	HANDLE  handle[THREAD_NUM];	
    	g_nNum = 0;
    	int i = 0;
    	while (i < THREAD_NUM) 
    	{
    		handle[i] = (HANDLE)_beginthreadex(NULL, 0, Fun, &i, 0, NULL);
    		WaitForSingleObject(g_hThreadParameter, INFINITE);//等待信号量>0
    		++i;
    	}
    	WaitForMultipleObjects(THREAD_NUM, handle, TRUE, INFINITE);
    	
    	//销毁信号量和关键段
    	DeleteCriticalSection(&g_csThreadCode);
    	CloseHandle(g_hThreadParameter);
    	for (i = 0; i < THREAD_NUM; i++)
    		CloseHandle(handle[i]);
    	return 0;
    }
    unsigned int __stdcall Fun(void *pPM)
    {
    	int nThreadNum = *(int *)pPM;
    	ReleaseSemaphore(g_hThreadParameter, 1, NULL);//信号量++
    
    	Sleep(50);//some work should to do
    
    	EnterCriticalSection(&g_csThreadCode);
    	++g_nNum;
    	Sleep(0);//some work should to do
    	printf("线程编号为%d  全局资源值为%d\n", nThreadNum, g_nNum);
    	LeaveCriticalSection(&g_csThreadCode);
    	return 0;
    }

    运行结果如下图:

    可以看出来,信号量也可以解决线程之间的同步问题。

     

    由于信号量可以计算资源当前剩余量并根据当前剩余量与零比较来决定信号量是处于触发状态或是未触发状态,因此信号量的应用范围相当广泛。本系列的《秒杀多线程第十篇 生产者消费者问题》将再次使用它来解决线程同步问题,欢迎大家参阅。

     

    至此,经典线程同步问题全部结束了,下一篇《秒杀多线程第九篇 经典多线程同步问题总结》将会对其作个总结以梳理各知识点。

     

    转载请标明出处,原文地址:http://blog.csdn.net/morewindows/article/details/7481609

    如果觉得本文对您有帮助,请点击支持一下,您的支持是我写作最大的动力,谢谢。

     

    展开全文
  • 说说四核八线程

    千次阅读 2016-10-28 22:13:04
    这年头卖电脑的都说咱家这个电脑是四核八线程的,打游戏,干什么都没有问题,流畅得很。那么四核八线程是什么意思??你一问,他就懵逼。今天来谈一下所谓的四核八线程是个什么鬼。 四核指四个核心,也就是四个cpu ...
  • 用户级线程和内核级线程区别

    千次阅读 2019-03-28 15:29:37
    用户级线程和内核级线程区别用户线程优点:缺点:内核级线程优点:缺点:关联性 线程的实现可以分两类:用户级线程,内核级线程和混合式线程。 用户线程 用户级线程是指不需要内核支持而在用户程序中实现的线程,...
  • 线程

    2021-04-09 18:41:58
    八 多线程八 多线程1 基本概念:程序、进程、线程2 线程的创建使用3 线程的生命周期4 线程的同步5 线程的通信6 JDK5.0新增线程的创建方式 八 多线程 1 基本概念:程序、进程、线程 2 线程的创建使用 3 线程的...
  • 线程()线程队列

    千次阅读 2017-03-31 09:13:50
    本文参考以下文章整理而成,希望大家多多指教!共同学习!原文地址如下:Java 并发工具包...Java线程(篇外篇):阻塞队列BlockingQueue引言  在上一篇多线程(七)线程池详解中提到了线程队列,相信大家现在已清楚明白线
  • 线程编程
  • 线程八

    千次阅读 2020-01-13 12:50:19
    一、线程八锁 1.两个普通同步方法,两个线程,标准打印,打印?//one two 2.新增Thread.sleep() 给getOne,打印?one two 3.新增普通方法getThree(),打印?//three one two 4.两个普通同步方法,两个Number对象,打印...
  • 线程和八大排序三大查找

    千次阅读 2012-05-16 16:11:20
    程序员必知的大排序和三大查找 http://blog.csdn.net/shan9liang/article/details/7533466 http://blog.csdn.net/shan9liang/article/details/7540928 ...   秒杀多线程面试题系
  • 四核八线程

    千次阅读 2018-10-05 19:10:41
    四核八线程   四个物理核心,模拟成八个逻辑核心。 因为使用了超线程技术 , 把一个物理核心模拟成两个逻辑核心, 就像八个物理核心一样在同一时间可以执行八个线程。  ...
  • 处理多线程问题时, 多个线程访问同一个对象,并且某些线程还想修改这个对象,这时候我们就需要线程同步,线程同步其实就是一种等待机制,多个需要同时访问此对象的线程进入这个对象的等待池形成队列,等待前面线程...
  • 结合多线程的学习过程,介绍线程的状态图,随着学习的深入,这幅图不断加入新的内容。   一.线程基本状态图  这幅图是在Java 多线程(三) 线程的生命周期及优先级出现过的:  图中是线程运行的...
  • 线程:并发调试JDK8新特性

    千次阅读 2018-06-08 08:21:11
    到了这章,多线程的介绍也到尾声了,最后介绍一下多线程在Eclipse中是怎么调试的,还有常见问题的解决方案。 多线程调试的方法 使用Eclipse进行多线程调试 -条件断点 以上示例断点会中断当前线程,...
  • JAVA中的多线程():线程的优先级yield方法 优先级代表着抢资源的频率 所有线程默认优先级是5 yield()临时释放线程的执行权 1 class Demo implements Runnable 2 { 3 public void run...
  • 程序中所说的线程、进程, CPU的线程(如四核八线程)有什么区别
  • ios - 多线程:GCD线程

    千次阅读 2017-05-12 15:17:10
    在我们的实际开发过程中会碰到这样的问题,只有当任务1任务2都完成之后才能执行任务3,这种情况下就需要线程组的出现来解决这类问题。常用方法注意事项:使用线程组的方法来创建任务是没有同步任务的,创建按钮...
  • 线程和并发库应用-线程池

    千次阅读 2018-01-06 21:58:25
    newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。 newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待...
  • 1、AbstractOwnableSynchronizer,设置 获取独占锁的拥有者线程。 可以由线程以独占方式拥有的同步器。此类为创建锁相关同步器(伴随着所有权的概念)提供了基础。AbstractOwnableSynchronizer 类本身不管理或...
  • Java线程(二):线程同步synchronizedvolatile

    万次阅读 多人点赞 2012-04-04 10:49:28
    要说明线程同步问题首先要说明Java线程的两个特性,可见性有序性。多个线程之间是不能直接传递数据交互的,它们之间的交互只能通过共享变量来实现。拿上篇博文中的例子来说明,在多个线程之间共享了Count类的一个...
  • java多线程)为什么弃用stopsuspend

    万次阅读 多人点赞 2015-08-27 09:12:23
    这两个方法在Java SE 1.2之后就被弃用了,因为这两种方法都不安全,下面我们分别来讨论一下为什么不安全应该怎样做才是安全的。 一、stop方法为什么不安全 其实stop方法天生就不安全,因为它在终止一个线程时...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 141,542
精华内容 56,616
关键字:

十六线程和八线程区别