一、如何创建多线程

1、继承Thread类

public class MyThread extends Thread {
    @Override
    public void run() {
        super.run();
        System.out.println("MyThread");
    }
}

public class Run {
    public static void main(String [] args){
        MyThread thread = new MyThread();
        thread.start();
    }
}

这里需要注意的是,run()方法里写的是线程执行的动作,而start()是创建线程并运行。

2、实现Runable接口

public class MyRunnable implements Runnable{
    private int num;
    public MyRunnable(){
        num++;
    }
    @Override
    public void run(){
        System.out.println("It's the " + num + " Thread");
    }
}

public class Run {
    public static void main(String [] args){
        MyRunnable runnable = new MyRunnable();
        Thread thread = new Thread(runnable);
        thread.start();
        System.out.println("运行结束");
    }
}

二、线程的状态

https://user-gold-cdn.xitu.io...

三、上下文切换

在一个核运行线程时,如果当前线程需要暂停转去运行其他线程,这个行为就叫做上下文切换
但是某个线程暂停转去运行其他线程后,要恢复这个线程时,需要从上次暂停的地方继续执行,这就需要CPU记录一些数据来帮助恢复。(比如程序计数器,CPU寄存器等等)
因此可以说,上下文切换就是存储和恢复CPU状态的,能够使线程从断点继续执行。

四、Thread常用方法

https://user-gold-cdn.xitu.io...

1、类方法

(1)sleep()方法

这个方法是让线程暂停(休眠)一段时间。

sleep(long millis)     //参数为毫秒
sleep(long millis,int nanoseconds)    //第一参数为毫秒,第二个参数为纳秒

调用了sleep()方法,被休眠的线程会让出CPU给其他线程,但是需要注意的是,它不会让出锁,也就是说线程虽然休眠了,但是依旧保持本来有的锁。
另外,当休眠时间结束之后,并不一定会立即执行,因为此时可能还有其他线程在执行。

(2)yield()方法

yield()与sleep()方法类似,同样让出CPU,不让出对象锁。但是不同点在于,yield不会传入参数,并且调用yield后,线程会进入就绪状态,随时等待重新获得CPU时间片。而调用sleep后,线程会进入阻塞状态

并且,yield方法只允许和当前线程拥有相同优先级的线程获取CPU。

2、对象方法

(1)isAlive()方法
判断当前线程是否活跃。活跃是指线程处于就绪或者运行的状态。

(2)join()方法
如果一个主线程启动了一个子线程,并且希望子线程执行完毕后再结束,那么就可以调用join()方法,即等待线程对象销毁

(3)setDaemon和isDaemon方法
用来设置线程是否成为守护线程和判断线程是否是守护线程。
守护线程依赖于创建它的线程,随它的消亡而消亡。

https://user-gold-cdn.xitu.io...

3、其他方法

(1)线程的停止

停止线程一般有三种方法:
① 调用stop()函数,这个方法实际上已经废弃了,因为它会立即终止线程,并且会释放所有的锁,因此可能会造成不可预期的结果。
自定义一个变量,当这个变量发生改变时,提醒线程终止。
③ 使用JDK提供的interrupt方法,提醒线程终止,但是否真正终止由线程自己决定。
(注意:线程在休眠时中断,会抛出异常,此时只能通过interrupt方法)

(2)wait和notify方法

这两个方法是Object类的方法,也就是说对所有对象都可以调用。

调用了wait方法,线程就会停止执行,进入一个队列中,等待notify方法去唤醒,但是notify方法只会随机唤醒一个线程,而notifyAll可以唤醒所有线程。
需要注意的是wait会释放锁,这是与sleep的不同之处。

参考:《实战Java高并发程序设计》
Java 多线程干货系列—(一)Java 多线程基础 https://juejin.im/post/5907bb...


hushucheng
42 声望2 粉丝