Thread线程对象

线程,是进程下面的一个单位,一个进程可以由很多个线程组成。为了提高CPU的使用率,Java提供了多线程编程。今天,就让我们来学习一下Java里面多线程最基础的一个类Thread。

1.线程的状态: NEW、RUNNABLE、BLOCKED、WAITING、TIMED_WAITING、TERMINATED。

2.每个Thread都有一个优先级priority,优先级高的线程优先执行。优先级的大小可通过setPriority(int newPriority)设置,范围是   [1,10],超过该范围会抛出IllegalArgumentException。

3.Java线程分为用户线程和守护线程,它们的区别在于:主线程结束后,用户线程依旧会执行,JVM处于存活状态;主线程结束后,如果没有用户线程(全都是守护线程),那么守护线程结束,JVM关闭。守护线程也称为服务线程,主要是为了给用户线程提供服务,在没有用户线程可服务时会自动消亡。Thread可以通过setDaemon(boolean on)设置。

4.eg:用户线程,JVM启动调用main函数的线程。守护线程,GC线程。

5.新创建的线程的优先级跟父线程一致,是否是守护线程也跟父线程一致。

//thread构造方法   
private void init(ThreadGroup g, Runnable target, String name,
                      long stackSize, AccessControlContext acc) {
        
        ...
        //得到父线程
        Thread parent = currentThread();
        
        ...
        //设置子线程daemon和priority为父线程的值
        this.daemon = parent.isDaemon();
        this.priority = parent.getPriority();
        setPriority(priority);
       
    }

6.Java虚拟机会持续运行Java线程,直到下面任何一种情况发生:

  • Runtime的exit方法被执行
  • 所有的用户线程都结束了

7.start()方法,用于启动线程。线程启动后,Java虚拟机就会执行线程的run方法。注意,任何线程都不能重复启动,否则会报IllegalThreadStateException。

8.线程中断。Java的线程中断实际上只是修改线程的中断标志,线程真正停止需要线程自己控制。

  • interrupt()方法。如果线程通过调用wait()、wait(long)、wait(long,int)、join()、join(long)、join(long,int)、sleep(long)、sleep(long,int)方法处于阻塞状态,此时调用interrupt()方法,会清除它的中断状态,并会抛出InterruptedException。如果线程被阻塞在一个Selector选择器中,那么调用interrupt()中断它时,中断标记会被置位true,并且立即从选择器返回。如果不属于前面两种情况,那么调用interrupt()中断它时,中断标记会被置位true,不会抛出异常。另外,中断一个“已终止的线程”,不会发生任何操作。
  • isInterrupted()方法,判断线程的中断标记是否为true。
  • interrupted()方法,返回并清除中断标记。

8.4.线程中断的方法:

import java.util.concurrent.TimeUnit;

public class TestThreadInterrupt {

	public static void main(String[] args) {
		Thread thread = new Thread(new WorkerThread());
		thread.start();
		
		try {
			TimeUnit.SECONDS.sleep(6l);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		
		thread.interrupt();
	}

}

class WorkerThread implements Runnable {
	@Override
	public void run() {
		while (true) {
			// 中断状态判断
			if (Thread.currentThread().isInterrupted()) {
				break;
			}
			System.out.println("do work");
			try {
				TimeUnit.SECONDS.sleep(3l);
			} catch (InterruptedException e) {
				System.out.println("I was interrupted");
				// 由于sleep方法中断的时候会清除中断标志,所以需要重设中断标志
				Thread.currentThread().interrupt();
			}
		}
	}
}

9.yield(),线程让步。当一个线程使用了yield()方法后,它会让出CPU执行时间,让自己或者其他线程运行。注意,此处是让自己或其他线程运行,并不是单纯的让给其他线程。另外,优先级高的线程会优先执行。

扫描二维码关注公众号,回复: 5933556 查看本文章
public class TestThreadYield {

	public static void main(String[] args) {
		Thread thread0 = new Thread(new Runnable() {
			@Override
			public void run() {
				for (int i = 0; i < 5; i++) {
                                        //thread0让出CPU
					Thread.yield();
					System.out.println(Thread.currentThread().getName());
				}
			}
		}, "thread0");
		Thread thread1 = new Thread(new Runnable() {
			@Override
			public void run() {
				for (int i = 0; i < 5; i++) {
					System.out.println(Thread.currentThread().getName());
				}
			}
		}, "thread1");
		thread0.start();
                //CPU设为最大优先级
		thread1.setPriority(Thread.MAX_PRIORITY);
		thread1.start();
	}

}

10.join(long millis)。等待最多millis毫秒直到该线程结束。millis为0表示一直等待直到该线程结束。

package com.code.thread;

public class TestThreadJoin {

	public static void main(String[] args) {
		Thread thread0 = new Thread(new Runnable() {
			@Override
			public void run() {
				for (int i = 0; i < 5; i++) {
					System.out.println(Thread.currentThread().getName());
				}
			}
		}, "thread0");
		Thread thread1 = new Thread(new Runnable() {
			@Override
			public void run() {
				for (int i = 0; i < 5; i++) {
					System.out.println(Thread.currentThread().getName());
				}
			}
		}, "thread1");
		thread0.start();
		try {
			//等待线程thread0直到结束
			//注意join方法必须在start后面
			thread0.join();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		thread1.start();
	}
}

11.线程顺序执行的方法

  • join(),参考上面的代码
  • 单线程线程池
package com.code.thread;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ThreadInTurn {

	public static void main(String[] args) {
		ExecutorService executor = Executors.newSingleThreadExecutor();
		
		Runnable a = new Runnable() {
			@Override
			public void run() {
				for (int i = 0; i < 5; i++) {
					System.out.println("Runnable a");
				}
			}
		};
		
		Runnable b = new Runnable() {
			@Override
			public void run() {
				for (int i = 0; i < 5; i++) {
					System.out.println("Runnable b");
				}
			}
		};
		
		executor.execute(a);
		executor.execute(b);
		executor.shutdown();
	}

}

12.线程变量ThreadLocal,它是跟线程绑定的变量。如果我们需要定义跟线程相关的变量,那么我们可以使用ThreadLocal。

 

 

 

猜你喜欢

转载自blog.csdn.net/u014730001/article/details/81344211