java.lang.Thread 类中提供了大量的相关的方法:
new Thread();
new Thread(name);
new Thread(Runnable,name);
new Thread(Runnable)
常用方法:
getId() :获取线程的唯一标识
getName() :获取线程名
getPriority():获取线程的优先级: 优先级从1-10 , min-priority:1 max-priority:10 norm- priority:5 注意说明优先级高的获取到cpu资源的概率越大,并不是一定会优先执行完成。
currentThread():获取当前线程的对象引用
getState():获取线程的状态 (这是返回线程状态的枚举, NEW:未启动,RUNABLE:可运行 BLOCK:阻塞状态, WAITING:等待状态TIMED-WAITIN: 等待另一个线程执行完)
interrupt():中断这个线程
isInterrupted(): 返回boolean 测试当前线程是否中断
isAlive():该线程是否处于活动状态
isDaemon():判断该线程是否是守护线程
setDaemon():设置该线程是否是守护线程
join() :合并线程,使它变为单线程
sleep(ms) :让当前线程休眠 ,休眠时间到了,自动唤醒
yield(): 让出cpu资源,使当前线程处理可运行状态(可运行状态也随时可以获取cpu资源)
案例1: 测试线程的基本属性
System.out.println("当前主线程:"+Thread.currentThread().getName());
System.out.println("主线程id:"+Thread.currentThread().getId());
//设置主线程的线程级别
Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
System.out.println("主线程的线程级别:"+Thread.currentThread().getPriority());
// 创建线程对象
MyThread my = new MyThread();
//设置线程名
my.setName("线程A");
//设置优先级
my.setPriority(10);
my.start();
MyThread my1 = new MyThread();
my1.setName("线程B");
//设置优先级 线程A 获取到资源的概率 大于线程B (大概率线程A优先执行完)
my1.setPriority(1);
//新生态
System.out.println("线程"+my1.getName()+"状态-----"+my1.getState());
my1.start();
//可运行状态(就绪)
System.out.println("线程"+my1.getName()+"状态-----"+my1.getState());
for(int i = 0;i<100;i++){
System.out.println("主线程------"+i);
}
守护线程
案例2: 守护线程
线程类型分为两种 一种是用户线程一种是守护线程,用户线程是执行某一个任务的独立代码 ,守护线程是用于守护用户线程的线程, 它的特点是 当用户线程执行完毕后守护现在自动结束,当用户线程没有执行完, 守护线程也不会停止
操作系统中有守护进程 ,用于操作系统的运行,只有关机进程自动结束,这里守护线程和守护进程类似。
//创建线程对象
DaemonThread daemonThread = new DaemonThread();
//设置该线程为守护线程 守护的是与它并行的线程类 ,当主线程或其他线程执行完毕,守护线程自动结束
// daemonThread.setDaemon(true);
System.out.println("是否是守护线程:"+daemonThread.isDaemon());
daemonThread.start();
for(int i=0;i<100;i++){
System.out.println("主线程i------"+i);
}
活动的线程总数: Thread.activeCount()
线程中断
案例3: 关于终止线程
线程中止就是当线程运行时由于满足特定的条件需要停止运行,此时我们需要考虑如何安全的中止线程这里中止线程提供几个方法
方法1 : 打标记中断法
线程运行1000,当程序达到500时,中止程序
public class ThreadEnd extends Thread {
@Override
public void run() {
boolean isOver=false;
for(int i = 0 ;i<1000;i++){
if(i>=500){
isOver= true;
return ;
}
System.out.println("线程结果i-----------"+i);
}
System.out.println("正常结束");
}
public static void main(String[] args) {
ThreadEnd th = new ThreadEnd();
th.start();
}
}
方法2: 异常中断法
- interrupt() :给线程打一个中断标记,不会立马中断
- interrupted() : 检测线程是否中断,并清除中断标记,返回boolean ,如果线程打标记了,就返回true
- isInterrupted() : 检测线程是否中断,但不清除中断标记, 返回boolean
注意用法: interrupted() : 它所处于的位置,对应于它作用的位置 ,通过线程类名调用
interrupt() 和 isInterrupted() : 使用线程对象调用。
public class Thread1 extends Thread {
@Override
public void run() {
int i =0;
while(true){
System.out.println("线程--------------"+i);
//判断当前线程是否有中断标记 ,但是不清除中断标记
if(this.isInterrupted()){
// 通过抛出异常或 break
System.out.println("当前线程打中断标记,可以停止了");
break;
}
i++;
}
}
}
public static void main(String[] args) throws InterruptedException {
Thread1 th = new Thread1();
th.start();
// 休眠一会儿
Thread.sleep(2000);
//给th打中断标记
System.out.println("打标记");
th.interrupt(); //给th打标记
}
3个方法的用法
// Thread.currentThread().interrupt();
// System.out.println("判断当前线程是否打标记 (清除标记):"+ Thread.interrupted());
System.out.println("判断线程是否打标记(不清除标记)"+ Thread.currentThread().isInterrupted());
System.out.println("判断当前线程是否打标记 (清除标记):"+ Thread.interrupted()); // 静态方法
join用法
案例四: join的用法: 合并当前线程 ,使其变为单线程 ,哪个线程调用join方法,就立即将该线程剩下的部分执行完成,再执行其他线程
public class ThreadJoin extends Thread {
@Override
public void run() {
ThreadJoin2 th = new ThreadJoin2();
th.setName("线程C");
th.start();
for(int i=0;i<100;i++){
try {
th.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"-----"+i);
}
}
}
public static void main(String[] args) throws InterruptedException {
ThreadJoin threadJoin = new ThreadJoin();
threadJoin.setName("线程A");
threadJoin.start();
// ThreadJoin threadJoin2 = new ThreadJoin();
// threadJoin2.setName("线程B");
// threadJoin2.start();
for(int i=0;i<100 ;i++){
if(i==50){
// 合并线程 (threadJoin线程的所有代码合并到 主线程中,先执行threadJoin线程)
threadJoin.join();
}
// if(i==70){
// threadJoin2.join();
// }
System.out.println("main---"+i);
}
}
sleep用法
案例五: sleep的用法: 用于休闲当前线程 ,休眠时间结束后自动唤醒继续执行,如果同时有多个线程执行 ,如果线程没有同步的情况下,相互休眠不影响,资源被公用。
public static void main(String[] args) {
for(int i =0;i<10;i++){
try {
//让当前线程休眠200毫秒 200毫秒后自动唤醒线程 继续执行
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(i);
}
}
class ThreadSleep implements Runnable{
@Override
public void run() {
for(int i =0;i<100;i++){
try {
Thread.sleep(1000); // 当前线程休眠时 不影响其他线程执行
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"----"+i);
}
}
}
ThreadSleep obj = new ThreadSleep();
Thread th1 = new Thread(obj , "线程A");
Thread th2 = new Thread(obj , "线程B");
th1.start();
th2.start();
yield用法
案例六:yield的用法 : 出让cpu, 让当先线程变为可运行状态 ,并也可以继续抢占cpu资源
public static void main(String[] args) {
ThreadYiled th = new ThreadYiled();
th.start();
// yield 让出cpu资源
for(int i = 0;i<100;i++){
if(i==50){
//主线程让cpu
System.out.println("让出cpu");
Thread.currentThread().yield();
}
System.out.println("主线程----"+i);
}
}