多线程--线程创建和常见方法

一. 线程创建

Java 提供了两种以编程方式创建线程的方法。

  1. 实现 java.lang.Runnable 接口。
  2. 扩展 java.lang.Thread 类

Runnable接口

Runnable接口用来指定每个线程要执行的任务, 还需要通过Thread来调用开启线程.

class ThreadTest1 implements Runnable {
    @Override
    public void run() {
        System.out.println("ThreadTest2.run");
    }
}
public class Demo {
	public static void main(String[] args) {
		Thread t1 = new Thread(new ThreadTest1);
		t1.start;
	}
}

Thread类

继承Thread类, 然后创建这个类的实例, 继承该类必须重写run()方法

class ThreadTest2 extends Thread {
    @Override
    public void run() {
        System.out.println("ThreadTest1.run");
    }
}
public class Demo {
	public static void main(String[] args) {
		ThreadTest1 t2= new ThreadTest2();
        t1.start();		
	}
}

Thread类常用构造方法

Thread() - 创建线程对象
Thread(Runable target) - 根据Runable对象创建线程
Thread(String name) - 创建一个名为name的线程
Thread(Runable target, String name) -根据Runable对象创建名为name的线程

Thread常用属性

属性获取方法
IDgetId()
名称getName()
状态getState()
优先级getPriority()
是否后台线程isDaemon()
是否存活isAlive()
是否被中断isInterrupted()

由于Java不支持多继承, 所以更多的使用接口实现线程

当我们创建出线程之后, 并不代表线程就在运行了, 当调用start()方法之后, 线程也开始执行

二. 线程中断

线程执行完之后会自动中断, 如果想让线程在执行过程中发生中断有两种方式

  1. 通过共享的标志位判断
  2. 通过 interrupt() 方法

第一种方式:

public class ThreadTest {
	  // 线程共享的标志位
    public static boolean flag = false;
    public static void main(String[] args) throws InterruptedException {
        Thread t1 = new Thread() {
            @Override
            public void run() {
                while(!flag) {
	                System.out.println("t1.run");
                    try {
                    		// t1线程休眠1000ms                    
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        };
        t1.start();
        // main线程休眠5000ms
        Thread.sleep(5000);
        flag = true;
    }
}

通过标志位的方式我们会发现, 当一个程序中出现多个线程需要中断, 不可能都用这一个标志位的方式,所以我们来看interrupt()

// 判断当前线程的中断标志位是否设置,调用后清除标志位
// 属于静态的 每个程序一个标志
public static boolean interrupted()
// 判断对象关联的线程的标志位是否设置,调用后不清除标志位
// 每个实例一个标志
public boolean isInterrupted()
public class ThreadTest06 {
    public static void main(String[] args) {
        Thread t1 = new Thread() {
            @Override
            public void run() {
                while(!Thread.currentThread().isInterrupted()) {
                    System.out.println("t1.run");
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                        System.out.println("结束!");
                        break;
                    }
                }
            }
        };
        t1.start();
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        t1.interrupt();
    }

sleep()

  1. 它可以暂停线程的执行
  2. 线程在执行之前的睡眠时间取决于系统调度的时间, 当系统不忙时, 该时间接近于指定睡眠时间, 当系统忙时, 该时间大于指定睡眠时间.
  3. 线程睡眠不会丢失当前线程已获得的任何监视器或锁。
  4. 线程在睡眠时发生阻塞,等待会抛出InterruptedException

三. 线程等待

join()

在当前线程调用另一个线程的join()方法, 会将当前线程挂起, 直到另一个线程结束.

public static void main(String[] args) throws InterruptedException {
    // 通过Lambda表达式创建线程
    Thread t1 = new Thread(() -> {
        for (int i = 0; i < 5; i++) {
            System.out.println("t1.run");
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    });

    t1.start();
    t1.join();
    for (int i = 0; i < 5; i++) {
        System.out.println("main.run");
        Thread.sleep(200);
    }
}

执行结果

t1.run
t1.run
t1.run
t1.run
t1.run
main.run
main.run
main.run
main.run
main.run

在mian线程调用t1线程的join方法, 只有当t1线程执行完毕才执行main线程

join() 方法会死等, 当调用的线程是一个死循环时, 就造成整个线程进入死循环. 可以加入等待时间

// 等待线程结束,最多等 millis 毫秒
public void join(long millis) 

四. 获取线程实例

通过Thread.currentThread() 方法可以获得当前线程对象的引用

public static void main(String[] args) throws InterruptedException {
        Thread t1 = new Thread(() -> {
            Thread thread = Thread.currentThread();
            System.out.println(thread);
        });

        t1.start();
        System.out.println(Thread.currentThread());
}

执行结果

Thread[main,5,main]
Thread[Thread-0,5,main]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

IT自习小空间

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值