• Java多线程常见概念


    参考资料:https://redspider.gitbook.io/concurrent/

    进程和线程的区别

    进程是一个独立的运行环境,而线程是在进程中执行的一个任务。他们两个本质的区别是是否单独占有内存地址空间及其它系统资源(比如I/O)

    • 进程单独占有一定的内存地址空间,所以进程间存在内存隔离,数据是分开的,数据共享复杂但是同步简单,各个进程之间互不干扰;而线程共享所属进程占有的内存地址空间和资源,数据共享简单,但是同步复杂。

    • 进程单独占有一定的内存地址空间,一个进程出现问题不会影响其他进程,不影响主程序的稳定性,可靠性高;一个线程崩溃可能影响整个程序的稳定性,可靠性较低。

    • 进程单独占有一定的内存地址空间,进程的创建和销毁不仅需要保存寄存器和栈信息,还需要资源的分配回收以及页调度,开销较大;线程只需要保存寄存器和栈信息,开销较小。

     线程组(ThreadGroup)

    每个Thread必然存在于一个ThreadGroup中,Thread不能独立于ThreadGroup存在。执行main()方法线程的名字是main,如果在new Thread时没有显式指定,那么默认将父线程(当前执行new Thread的线程)线程组设置为自己的线程组。

    Start和run的区别

    Start()会创建一个新的子线程并启动

    Run()只是Thread的一个普通方法的调用

    Thread和Runnable关系

    Thread是实现了Runnable接口的类,使得run支持多线程

    因类的单一继承原则,推荐多使用Runnable接口

     1     public static void main(String[] args) {
     2        
     3         new Thread(new Runnable() {
     4             public void run() {
     5                 System.out.println("Runnable running..");
     6             }
     7         }) {
     8             public void run() {
     9                 System.out.println("Thread running..");
    10             };
    11         }.start();
    12     }

    输出结果为

    Thread running..

    继承Thread类,那么在调用start的方法时会去调用Thread的子类的方法

    如何给run()方法传参

    构造函数传参

    成员变量传参

    回调函数传参

    如何实现处理线程的返回值

    主线程等待法(新建一个属性来存返回值,当这个属性还没值的时候,就等待,直到它有值)

    使用Thread类的join()阻塞当前线程以等待子线程处理完毕

    通过Callable接口实现,通过FutureTask 或线程池获取(推荐)

    Sleep和wait区别

    Sleep是Thread类的方法,wait是Object类的方法

    Sleep方法可以在任何地方使用

    Wait方法只能在synchronized方法或synchronized块中使用

    Thread.sleep只会让出CPU,不会导致锁行为的改变

    Object.wait不仅让出CPU,还会释放已经占有的同步资源锁

     1 public class ThreadTest {
     2     public static void main(String[] args) {
     3         final Object lock = new Object();
     4         new Thread(new Runnable() {
     5             @Override
     6             public void run() {
     7                 System.out.println("A is waiting to get lock");
     8                 synchronized (lock) {
     9                     try {
    10                         System.out.println("A get lock");
    11                         Thread.sleep(20);
    12                         System.out.println("A get do wait method");
    13                         Thread.sleep(1000);//只会让出CPU,不会导致锁行为的改变
    14                         System.out.println("A is done");
    15                     } catch (InterruptedException e) {
    16                         e.printStackTrace();
    17                     }
    18                 }
    19             }
    20         }).start();;
    21         try {
    22             Thread.sleep(10);// 让A先执行
    23         } catch (InterruptedException e1) {
    24             e1.printStackTrace();
    25         }
    26         new Thread(new Runnable() {
    27             @Override
    28             public void run() {
    29                 System.out.println("B is waiting to get lock");
    30                 synchronized (lock) {
    31                     try {
    32                         System.out.println("B get lock");
    33                         System.out.println("B is sleeping 10 ms");
    34                         lock.wait(10);//不仅让出CPU,还会释放已经占有的同步资源锁
    35                         System.out.println("B is done");
    36                     } catch (InterruptedException e) {
    37                         e.printStackTrace();
    38                     }
    39                 }
    40             }
    41         }).start();;
    42     }
    43 }
    举例

    等待池

    假设线程A调用了某个对象的wait()方法,线程A就会释放该对象的锁,同时线程A就进入到了该对象的等待池中,进入到等待池中的线程不会去竞争该对象的锁

    Notify和notifyAll区别

    notifyAll会让所有处于等待池的线程全部进入锁池去竞争获取锁的机会

    notify只会随机选取一个处于等待池中的线程进入锁池去竞争获取锁的机会

    yield

    当调用Thread.yield()函数时,会给线程调度器一个当前线程愿意让出CPU使用的暗示,但是线程调度器可能会忽略这个暗示

    Interrupt

    如果线程处于被阻塞状态,那么线程将立即退出被阻塞状态,并抛出一个InterruptedException异常。

    如果线程处于正常活动状态,那么会将该线程的中断标志设为true,被设置中断标志的线程将继续正常运行,不收影响。

  • 相关阅读:
    httpclient 发送 json数据,微信security.msgSecCheck,
    win10 输入法,添加美式键盘,调整顺序
    activiti与spring的集成
    spring 中实例化Bean的三种方式
    工作流activiti的HelloWorld
    工作流Activiti的前置准备工作。
    Eclipse中配置约束(DTD,XSD)
    微信开发中,本地缓存,不同步的问题
    微信开发中碰到的坑,json传值,前台遍历json对象,跨页面转值,navigate层级限制
    用pageInfo对List手工分页
  • 原文地址:https://www.cnblogs.com/flyuz/p/11320706.html
Copyright © 2020-2023  润新知