

























在学习和使用Java的多线程前,需要了解一些关于计算机中进程,线程的基础知识。
通过继承java.lang.Thread,重写其run()方法来创建自定义线程类,然后实例化该类并调用start()方法启动线程,jvm自动调用run()方法,run()方法运行的就是子线程。
start()方法执行后,线程不一定立即创建,因为线程是操作系统的资源,需要等待操作系统分配
1.可以通过重写带参(线程名)构造函数,或调用setName()设置线程名。
2.每个Thread只能执行一次run()方法否则会出现IllegalThreadStateException异常,如果我们自己直接运行线程的run()方法等同于对象调用方法,仍然是单线程。
3.通过Thread.currentThread()可以获取当前运行的线程。
class MyThread extends Thread {
public MyThread(String name) {
super(name);
}
@Override
public void run() {
System.out.println("Thread is running.");
System.out.println(Thread.currentThread().getName());
}
}
MyThread thread = new MyThread("t1");
thread.start();class MyThread extends Thread {
@Override
public void run() {
System.out.println("Thread is running.");
System.out.println(Thread.currentThread().getName());
}
}
MyThread thread = new MyThread();
thread.setName("t1");
thread.start();通过匿名内部类写法
new Thread("t1") {
@Override
public void run() {
System.out.println("Thread is running.");
System.out.println(Thread.currentThread().getName());
}
}.start();通过实现java.lang.Runnable接口并重写其run()方法实现一个Target对象,然后将该Target传递给Thread,同时可以选择指定一个线程名,再调用Thread的start()方法启动线程,jvm自动调用run()方法,在run()方法开启子线程。
实现Runnable接口创建子线程,既可以避免单继承的局限,又能使得代码更加清晰,把子线程的任务与执行任务的Thread对象分开,可以用一个任务创建出多个线程同时执行。
class MyRunnable implements Runnable {
@Override
public void run() {
System.out.println("Thread is running.");
}
}
Thread thread = new Thread(new MyRunnable());
thread.start();
Thread thread2 = new Thread(new MyRunnable(), "t2");
thread2.start();无论哪种方式创建线程,都不能自己手动调用Thread的
run()方法,必须调用start(),start()方法最终调用C++实现的native方法start0(),由JVM调用run()方法,所以自己调用run()方法无法实现多线程。
java.lang.Threadpublic synchronized void start() { /** * This method is not invoked for the main method thread or "system" * group threads created/set up by the VM. Any new functionality added * to this method in the future may have to also be added to the VM. * * A zero status value corresponds to state "NEW". */ if (threadStatus != 0) throw new IllegalThreadStateException(); /* Notify the group that this thread is about to be started * so that it can be added to the group's list of threads * and the group's unstarted count can be decremented. */ group.add(this); boolean started = false; try { start0(); started = true; } finally { try { if (!started) { group.threadStartFailed(this); } } catch (Throwable ignore) { /* do nothing. If start0 threw a Throwable then it will be passed up the call stack */ } } } private native void start0();
JVM的线程分为用户线程和守护线程
用户线程:系统的工作线程,会完成这个程序需要完成的业务操作。
守护线程:服务线程,没有服务对象就没有必要继续运行下去了。
Java中,通过设置setDaemon(true)来实现一个守护线程,需要在调用start()方法之前设置,当主线程结束后,守护线程即使还有任务未完成,JVM进程也会退出。如果子线程没有设置为守护线程,即使主线程完成,子线程仍然继续执行未完成的任务,JVM不会退出。
public static void main(String[] args) {
Thread daemon = new Thread(() -> {
System.out.println(Thread.currentThread().getName());
while (true) {
}
}, "daemon");
daemon.setDaemon(true);
daemon.start();
System.out.println(Thread.currentThread().getName());
}暂停执行(睡眠)多少毫秒,让出CPU,但是不释放锁
Thread.sleep(2000);通过Thread.sleep();使线程休眠,观测线程开启和结束后的状态。
public static void main(String[] args) {
Thread t1 = new Thread(() -> {
System.out.println(Thread.currentThread().getName());
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}, "t1");
t1.start();
System.out.println(t1.isAlive()); //true
try {
Thread.sleep(4000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println(t1.isAlive()); //false
}静态方法,当前线程让出CPU,给同级或更高优先级线程机会,不会释放锁。
Thread.yield();还有一些线程的方法涉及到线程间的通信,见:Java线程间的通信机制
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。