Java并发入门

目录

  • Thread类
    • 创建线程的方法
    • sleep方法
    • setDaemon方法设置守护线程
    • join方法
    • setPriority方法设置线程优先级
    • yield临时暂停
    • interrupt请求终止线程

Thread类

Java多线程使用Thread类实现,该类实现了接口Runnable。

创建线程的方法

创建线程有如下3种方法。

  1. 继承Thread,重写run方法。
  2. 实现Runnable接口,重写run方法。
  3. 实现Runnable接口,重写run方法。(使用lambda表达式实现)。

见如下代码:

public class Hello {
    public static void main(String[] args) {
        //如下是创建线程的3种方法。
        Thread t1 = new myThread();
        Thread t2 = new Thread(()->{
            System.out.println("hello!");
        });
        Thread t3 = new Thread(new myRunnable());
        t1.start();
        t2.start();
        t3.start();
    }
}

class myThread extends Thread {
    @Override
    public void run() {
        System.out.println("hello!");
    }
}

class myRunnable implements Runnable {
    @Override
    public void run() {
        System.out.println("hello!");
    }
}

**注意:**启动线程是start()方法,run()并不能启动一个新的线程(run方法是执行一次run函数,并不是启动线程)。

sleep方法

执行Thread.sleep(100)方法使当前线程暂停100毫秒。
当线程sleep时,如果被停止,则抛出InterruptedException
注意:当sleep时间到了以后线程进入的是就绪状态而非执行状态!

setDaemon方法设置守护线程

守护线程是为其他线程服务的,如垃圾回收线程。
特点:当一个进程里所有线程都是守护线程时,结束该进程。守护线程中产生的线程也是守护线程。

public class TestThread {
    public static void main(String[] args) {
        Thread t = new Thread(() -> {
            System.out.println(Thread.currentThread().getName());
            while (true) { 
                
            }
        }, "守护线程");
        t.setDaemon(true);
        t.start();
        System.out.println(Thread.currentThread().getName());
    }
}

结果:该程序正常退出了,并没有因为while (true) 卡死。

join方法

主线程:所有进程,至少会有一个线程即主线程,即main方法开始执行,就会有一个看不见的主线程存在。
调用join()方法主线程会等待该线程结束完毕, 才会往下运行。

public class TestThread {
    public static void main(String[] args) throws InterruptedException {
        Thread t = new Thread(() -> {
            try {
                Thread.sleep(10000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("线程睡眠结束!");
        });
        Thread t2 = new Thread(() -> {
            System.out.println("t2运行了");
        });
        t.start();
        //t.join();
        t2.start();
    }
}

运行结果:可以看到,当t.join()没有被注释时,会等待10秒以后才会输出"2运行了!

setPriority方法设置线程优先级

线程的优先级可以通过setPriority(int newPriority)方法设置。线程优先级高仅仅表示线程获取的CPU时间片的几率高,但这不是一个确定的因素!
Java并发入门_第1张图片
通过源码可以看到优先级的范围是1~10,默认优先级是5.

yield临时暂停

Thread.yield()方法可以暂停当前线程,让其他线程先执行。

interrupt请求终止线程

使用interrupt来请求终线程,要注意的是:interrupt不会真正停止一个线程,它仅仅是给这个线程发了一个信号告诉它,它应该要结束了(明白这一点非常重要!)也就是说:Java设计者实际上是想线程自己来终止,通过上面的信号,就可以判断处理什么业务了。具体到底中断还是继续运行,应该由被通知的线程自己处理。
检查该线程是否被中断有两个方法:

  1. 静态方法interrupted()–>会清除中断标志位
  2. 实例方法isInterrupted()–>不会清除中断标志位

注意:如果sleep或者wait的进程被请求中断会抛出异常。

import org.omg.PortableServer.THREAD_POLICY_ID;

public class ThreadTest {
    public static void main(String[] args) {
        Thread t = new Thread(() -> {
            int i = 0;
            while (!Thread.currentThread().isInterrupted()) {
                //如果当前线程没有被请求中断,则一直输出a
                System.out.println(i++);
            }
            System.out.println(Thread.currentThread().isInterrupted());
            System.out.println(Thread.interrupted());
            System.out.println(Thread.currentThread().isInterrupted());
        });
        t.start();
        new Thread(() -> {
            try {
                Thread.sleep(1000);
                t.interrupt();  //等待1秒后请求中断t
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }).start();
    }
}

输出结果:
Java并发入门_第2张图片
可以看到,调用静态方法以后,标志被清楚了。

你可能感兴趣的:(java,并发)