5-线程常用属性

目录

1.ID

2.名称

3.状态

4.优先级

5.是否守护线程

5.1.线程类型:

①用户线程(main线程默认是用户线程)

②守护线程(后台/系统线程)

5.2.守护线程作用

5.3.守护线程应用

5.4.守护线程使用

①在用户线程(main线程)中创建的子线程默认情况下也是用户线程

②在守护线程中创建的子线程默认情况下也是守护线程

③守护线程和用户线程的区别

6.是否存活

7.是否被中断

PS:线程执行顺序or随机判断准则


1.ID

是线程的唯⼀标识,不同线程ID不会重复,是动态分配的。(相当于进程PID)

2.名称

是各种调试⼯具⽤到,默认不同线程名称是不同的,但若手动指定不同线程名称可以重复。

/**
 * 线程属性:id、name
 */
public class ThreadDemo13 {
    public static void main(String[] args) throws InterruptedException {
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                //得到执行当前任务的线程
                Thread t = Thread.currentThread();
                //打印线程id(是long类型)
                System.out.println("线程ID:" + t.getId());
                //打印线程名称
                System.out.println("线程名称:" + t.getName());
            }
        };

        Thread thread = new Thread(runnable,"线程1");
        thread.start();

        Thread.sleep(500);
        System.out.println();

        Thread thread2 = new Thread(runnable,"线程1");
        thread2.start();
    }
}

3.状态

表示线程当前所处的⼀个情况。

/**
 * 线程状态的流转
 */
public class ThreadDemoByState {
    public static void main(String[] args) throws InterruptedException {
        Thread t = new Thread(new Runnable() {
            @Override
            public void run() {
                //拿到当前线程,并打印当前线程的状态
                Thread thread = Thread.currentThread();
                System.out.println("线程状态2:" + thread.getState());
            }
        });
        //打印线程的状态
        System.out.println("线程状态:" + t.getState());
        t.start();

        //再次打印线程状态
        Thread.sleep(500);
        System.out.println("线程状态3:" + t.getState());
    }
}

4.优先级

优先级⾼的线程理论上来说更容易被调度到。

线程创建之后,优先级就已经存在了。

/**
 * 获取线程优先级
 */
public class ThreadDemoByPriority {
    public static void main(String[] args) throws InterruptedException {
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                //得到当前线程,并打印线程优先级
                Thread t = Thread.currentThread();
                System.out.println("线程优先级:" + t.getPriority());
            }
        });
        System.out.println("线程优先级2:" + thread.getPriority());
        thread.start();
        Thread.sleep(500);
        System.out.println("线程优先级3:" + thread.getPriority());
    }
}

线程优先级是int类型值,为1-10,最小优先级是1,最高优先级是10,默认优先级是5。

设置线程优先级(2种):

t1.setPriority(Thread.MAX_PRIORITY);
t1.setPriority(10);
/**
 * 设置线程优先级
 */
public class ThreadDemoByPriority2 {
    private final static int MAX_COUNT = 7;
    public static void main(String[] args) {
        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                //得到当前线程
                Thread t = Thread.currentThread();
                //得到线程的优先级
                int priority = t.getPriority();
                for (int i = 0; i < MAX_COUNT; i++) {
                    System.out.println(t.getName() + "——优先级:" + priority);
                }
            }
        },"线程1");
        //设置线程优先级(2种写法)
//        t1.setPriority(10); //直接赋值
        t1.setPriority(Thread.MAX_PRIORITY); //枚举

        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                Thread t = Thread.currentThread();
                int priority = t.getPriority();
                for (int i = 0; i < MAX_COUNT; i++) {
                    System.out.println(t.getName() + "——优先级:" + priority);
                }
            }
        },"线程2");
        t2.setPriority(Thread.MIN_PRIORITY);

        Thread t3 = new Thread(new Runnable() {
            @Override
            public void run() {
                Thread t = Thread.currentThread();
                int priority = t.getPriority();
                for (int i = 0; i < MAX_COUNT; i++) {
                    System.out.println(t.getName() + "——优先级:" + priority);
                }
            }
        },"线程3");
        t3.setPriority(Thread.NORM_PRIORITY);

        //同时启动线程(非常快,可以认为是同时的)
        t2.start();
        t1.start();
        t3.start();
    }
}

多个线程设置了不同的优先级,同时启动这多个线程,并不是优先级最高的一定先执行完之后再执行优先级最低的线程,而是高优先级获取到CPU时间片的概率更多,整个执行大致符合高优先级的线程最先执行完。

快捷键设置:

ctrl+F查找

ctrl+H替换

5.是否守护线程

5.1.线程类型:

①用户线程(main线程默认是用户线程)

程序员创建的线程。

②守护线程(后台/系统线程)

5.2.守护线程作用

守护线程是为⽤户线程服务的,当一个程序中的所有⽤户线程全部结束之后,守护线程会跟随结束。

5.3.守护线程应用

JVM 中的垃圾回收器就是典型的守护线程,程序运⾏的时候它也运⾏,当满⾜条件时进⾏垃圾回收,在一个进程中所有非后台线程执⾏完任务终⽌时它才会结束运行。

5.4.守护线程使用

//获取当前线程是否是守护线程
thread.isDaemon()
//true->守护线程; false->用户线程
//手动指定线程类型
t1.setDaemon(true);
//true->守护线程; false->用户线程

①在用户线程(main线程)中创建的子线程默认情况下也是用户线程

/**
 * 守护线程示例
 */
public class ThreadDemoByDaemon {
    public static void main(String[] args) throws InterruptedException {
        //得到当前的线程(main主线程)
        Thread thread = Thread.currentThread();
        System.out.println(thread.getName() + "——是否是守护线程:" + thread.isDaemon());

        Thread t1 = new Thread(() -> {
            //得到当前线程
            Thread cThread = Thread.currentThread();
            System.out.println(cThread.getName() + "——是否是守护线程:" + cThread.isDaemon());
        },"子线程1");
        t1.start(); //启动线程
    }
}

通过这个示例可得出结论:

  1. main线程(主线程)默认是用户线程(非守护线程)。
  2. 在用户线程中创建的子线程也是用户线程。

②在守护线程中创建的子线程默认情况下也是守护线程

/**
 * 守护线程示例
 */
public class ThreadDemoByDaemon {
    public static void main(String[] args) throws InterruptedException {
        //得到当前的线程(main主线程/用户线程)
        Thread thread = Thread.currentThread();
        System.out.println(thread.getName() + "——是否是守护线程:" + thread.isDaemon());

        Thread t1 = new Thread(() -> {
            //得到当前线程t1
            Thread cThread = Thread.currentThread();
            System.out.println(cThread.getName() + "——是否是守护线程:" + cThread.isDaemon());

            //创建子线程tt1
            Thread tt1 = new Thread(() -> {
                Thread cThread2 = Thread.currentThread();
                System.out.println(cThread2.getName() + "——是否是守护线程:" + cThread2.isDaemon());
            },"子线程t1的子线程tt1");
            tt1.start();

        },"子线程t1");

        //手动指定线程t1为守护线程
        t1.setDaemon(true);
        t1.start(); //启动线程

        //主线程休眠1s
        Thread.sleep(1000);
    }
}

注:线程类型(用户or守护)不能在线程运行期间,也就是调用了 start() 之后设置,否则JVM会报错。

③守护线程和用户线程的区别

/**
 * 对比用户线程和守护线程的区别
 */
public class ThreadDemoByDaemon2 {
    public static void main(String[] args) throws InterruptedException {
        userThread();
        daemonThread();
    }

    /**
     * 用户线程
     */
    private static void userThread() {
        Thread thread = new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                System.out.println("用户线程执行:" + i);
                try {
                    Thread.sleep(200);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        thread.start();
    }

    /**
     * 守护线程
     */
    private static void daemonThread() {
        Thread t = new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                System.out.println("守护线程执行:" + i);
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        //设置为守护线程
        t.setDaemon(true);
        //启动线程
        t.start();
    }
}

结论:JVM会等待所有的用户线程执行完再自然退出,但JVM不会等待守护线程执行完再退出。若用户线程没执行完强制退出,JVM也会退出。

线程的类型和线程的调度无关,只有线程的优先级和线程的调度有关。

6.是否存活

简单的理解为 run ⽅法是否运⾏结束了。

public class ThreadDemoByAlive {
    public static void main(String[] args) throws InterruptedException {
        Thread t = new Thread(() -> {
           Thread thread = Thread.currentThread();
            System.out.println("线程是否存活2:" + thread.isAlive());
        });
        System.out.println("线程是否存活:" + t.isAlive());
        t.start();
        System.out.println("线程是否存活3:" + t.isAlive());
        Thread.sleep(1000);
        System.out.println("线程是否存活4:" + t.isAlive());
    }
}

使用场景:

public class ThreadDemoByAlive {
    public static void main(String[] args) throws InterruptedException {
        Thread t = new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                try {
                    Thread.sleep(200);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println("1:线程执行完了!");
        });
        t.start();
        while(t.isAlive()){
        }
        System.out.println("2:确认线程执行完了!");
    }
}

7.是否被中断

线程在休眠或执行当中,其他线程可以操作此线程让其中断。

PS:线程执行顺序or随机判断准则

  1. 在一个线程里的执行顺序是从上往下的。
  2. 多个线程之间的执行是随机的,因为线程调度是随机的。
public class ThreadDemo13 {
    public static void main(String[] args) throws InterruptedException {
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                //得到执行当前任务的线程
                Thread t = Thread.currentThread();
                //打印线程id(是long类型)
                System.out.println(t.getName() + "——线程ID:" + t.getId());//①
                //打印线程名称
                System.out.println(t.getName() + "——线程名称:" + t.getName());//②
                //打印线程优先级
                System.out.println(t.getName() + "——线程优先级:" + t.getPriority());//③
            }
        };

        Thread thread = new Thread(runnable,"线程1");
        thread.start();

        Thread thread2 = new Thread(runnable,"线程2");
        thread2.start();

        Thread thread3 = new Thread(runnable,"线程3");
        thread3.start();
    }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C语言中,线程相关的常用函数包括: 1. pthread_create ```c int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg); ``` 该函数用于创建一个新的线程,参数说明如下: - thread:指向线程标识符的指针,创建成功后会将线程的标识符返回给调用者。 - attr:指定线程属性,通常使用默认属性即可,传入NULL。 - start_routine:指向线程函数的指针,线程创建后会从该函数开始执行。 - arg:传递给线程函数的参数。 2. pthread_join ```c int pthread_join(pthread_t thread, void **retval); ``` 该函数用于等待一个线程结束,参数说明如下: - thread:等待的线程标识符。 - retval:指向线程返回值存储位置的指针,可以为NULL,表示不关心线程返回值。 3. pthread_detach ```c int pthread_detach(pthread_t thread); ``` 该函数用于将线程设置为分离状态,使得线程结束时能够自动释放资源,参数说明如下: - thread:需要分离的线程标识符。 4. pthread_exit ```c void pthread_exit(void *retval); ``` 该函数用于线程退出,参数说明如下: - retval:线程的返回值。 5. pthread_cancel ```c int pthread_cancel(pthread_t thread); ``` 该函数用于取消一个线程,参数说明如下: - thread:需要取消的线程标识符。 6. pthread_mutex_init ```c int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr); ``` 该函数用于初始化一个互斥锁,参数说明如下: - mutex:指向互斥锁的指针。 - attr:指定互斥锁的属性,通常使用默认属性即可,传入NULL。 7. pthread_mutex_destroy ```c int pthread_mutex_destroy(pthread_mutex_t *mutex); ``` 该函数用于销毁一个互斥锁,参数说明如下: - mutex:指向互斥锁的指针。 8. pthread_mutex_lock ```c int pthread_mutex_lock(pthread_mutex_t *mutex); ``` 该函数用于加锁一个互斥锁,参数说明如下: - mutex:指向互斥锁的指针。 9. pthread_mutex_unlock ```c int pthread_mutex_unlock(pthread_mutex_t *mutex); ``` 该函数用于解锁一个互斥锁,参数说明如下: - mutex:指向互斥锁的指针。 10. pthread_cond_init ```c int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr); ``` 该函数用于初始化一个条件变量,参数说明如下: - cond:指向条件变量的指针。 - attr:指定条件变量的属性,通常使用默认属性即可,传入NULL。 11. pthread_cond_destroy ```c int pthread_cond_destroy(pthread_cond_t *cond); ``` 该函数用于销毁一个条件变量,参数说明如下: - cond:指向条件变量的指针。 12. pthread_cond_wait ```c int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex); ``` 该函数用于等待一个条件变量,参数说明如下: - cond:指向条件变量的指针。 - mutex:指向互斥锁的指针。 13. pthread_cond_signal ```c int pthread_cond_signal(pthread_cond_t *cond); ``` 该函数用于唤醒一个等待条件变量的线程,参数说明如下: - cond:指向条件变量的指针。 14. pthread_cond_broadcast ```c int pthread_cond_broadcast(pthread_cond_t *cond); ``` 该函数用于广播一个条件变量,唤醒所有等待条件变量的线程,参数说明如下: - cond:指向条件变量的指针。 这些函数在不同的操作系统和编译器中可能有所不同,需要根据具体的使用情况来选择和调用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值