天天看点

Java LockSupport.park()根据信号调度原理

1. 有两个线程

一个线程等待信号,直到获取信号之后再执行下面的代码

一个线程向另一个线程发信号

jvm源码位置

jdk7u/jdk7u/hotspot: 677234770800 src/os/linux/vm/os_linux.cpp

2. c语言实现

signal_wake_up.c

#include<stdio.h>
#include <unistd.h>
#include<pthread.h>
#include <signal.h>
#include<time.h>

pthread_t pt, pt2;

void print_date(){
    time_t time1;
    time(&time1);
    struct tm* t1 = localtime(&time1);
    char buf[50];
    strftime(buf, 50, "%Y-%m-%d %H:%M:%S", t1);
    printf("%s\n", buf);
}

void* thread_run(void* arg){
    sigset_t set;
    sigaddset(&set, SIGALRM);
    for (;;){
        int sig;
        // 等待信号被唤醒
        sigwait(&set, &sig);
        printf("up %d\n", sig);
        print_date();
    }
}

void* thread_run2(void* arg){
    while (1){
        sleep(3);
        // 发送信号给pt线程
        pthread_kill(pt, SIGALRM);
    }
}

void sighandle(int num){
    printf("num %d\n", num);
}

int main(){
   signal(SIGALRM, sighandle);

   int ret1 = pthread_create(&pt, NULL, thread_run, NULL);
   
   if (ret1 == -1){
       perror("pthread_create");
       _exit(0);
   }

   int ret2 = pthread_create(&pt2, NULL, thread_run2, NULL);
   if (ret2 == -1){
       perror("pthread_create");
       _exit(0);
   }

   pthread_join(pt, NULL);
   pthread_join(pt2, NULL);
   return 0;
}
           

编译

gcc signal_wake_up.c -o sig_wake_up -lpthread
           

执行结果,

Java LockSupport.park()根据信号调度原理

 pt线程每3秒被唤醒一次

3.参考资料

jvm源码分析之LockSupport_lzf的博客-CSDN博客