多线程实现方式和常用方法

1 进程和线程

      进程Process: 每个进程都有独立的代码和数据空间(进程上下文),进程间的切换会有较大的开销,一个进程包含1--n个线程。可以把进程简单理解为操作系统中运行的一个程序。

      线程Thread:同一类线程共享代码和数据空间,每个线程有独立的运行栈和程序计数器(PC),线程切换开销小。

线程是进程的一个执行分支

创建线程就是创建Thread类(子类)的对象(实例)

java.lang.Thread 

  • public class Thread extends Object implements Runnable 

一个线程的周期

 

 

继承Thread类

class ThreadTest extends Thread{
    public void run(){
        System.out.println("这个线程开始运行");
    }
}
public class Test {
    public static void main(String[] args) {
        ThreadTest tt = new ThreadTest ();
        tt.start();    //启动一个线程
    }
}

实现Runnable接口

class ThreadTest implements Runnable{
    public void run(){
        System.out.println("这个线程开始运行");
    }
}
public class Test {
    public static void main(String[] args) {
        ThreadTest tt = new ThreadTest ();
        Thread t = new Thread(tt);
        t.start();       //通过一个线程对象启动它
    }
}

这两种方式的区别:

1、继承Thread类:编写简单,可直接操作线程。适用于单继承

2、实现Runnable接口:避免单继承局限性,便于共享资源。

 线程的优先级

ThreadTest t1 = new ThreadTest();
t1.setPriority(1);                     //设置成最低级
ThreadTest t2 = new ThreadTest();
t2.setPriority(10);                    //设置成*
t1.start();
t2.start();

Java线程有优先级,优先级高的线程会获得较多的CPU运行机会。Thread类的setPriority()和getPriority()方法分别用来设置和获取线程的优先级。 Java线程的优先级用整数表示,取值范围是1~10; 10*。每个线程都有默认的优先级。主线程的默认优先级为Thread.NORM_PRIORITY(5)

线程睡眠

class ThreadTest extends Thread{
    public void run(){
        for(int i=0;i<10;i++){
            System.out.println(i);
            try {
                Thread.sleep(1000);         //每隔一秒后输出
            } catch (InterruptedException e) {  //线程睡眠期间如果被打断,将抛出异常。
                e.printStackTrace();
            }
        }
    }
}

Thread.sleep() 强迫线程睡眠(单位:毫秒)

合并线程

join()的功能是:等待某线程结束,再恢复当前线程的运行

或者说:join()把指定的线程加入到当前线程,可以将两个交替执行的线程合并为顺序执行的线程

class ThreadTest extends Thread{
    public void run(){
        for(int i=0;i<10;i++){
            System.out.println(this.getName() + ":" + i);
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
//相当于将tt线程和main线程合并成一个线程。
//那么main线程会等待tt线程结束后再运行。
public static void main(String[] args) {
    ThreadTest tt = new ThreadTest ();
    tt.start();
    try {
        tt.join();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    for(int i=0;i<10;i++){
        System.out.println("main:" + i);
    }
}

让出CPU资源 

yield() 让出CPU资源,当前线程进入就绪状态

class ThreadTest extends Thread{
    public void run(){
        for(int i=0;i<100;i++){
            System.out.println(this.getName() + ":" + i);
            if(i%10==0){
                Thread.yield();
            }
        }
    }
}
public static void main(String[] args) {
    ThreadTest tt1 = new ThreadTest ();
    ThreadTest tt2 = new ThreadTest ();
    tt1.start();
    tt2.start();    
}

线程等待与唤醒

wait():当前线程进入等待状态,即进入等待池。(释放同步锁,由notify()唤醒);

notify()/notifyAll():唤醒等待池中的某个或全部等待线程。

 

上一篇:记录vue3中h函数的各种使用方式


下一篇:【算法】单调队列