第1 章 : Java多线程编程
2 进程与线程
进程 系统进行资源分配和调度的基本单位
线程 在进程基础上划分的更小的程序单元,操作系统能够进行运算调度的最小单位
Java多线程编程语言
3 Thread类实现多线程
1、继承Java.lang.Thread实现多线程
覆写run方法
start启动线程
每一个线程对象只能启动一次,多次启动就会抛出异常
native
JNI Java Nativa Interface 本地接口,针对不同操作系统有不同的实现
class MyThread extends Thread{
private String name;
public MyThread(String name){
this.name = name;
}
@Override
public void run(){
for (int i =0 ; i< 3; i++) {
System.out.println(this.name + " -> " + i);
}
}
}
class Demo{
public static void main(String[] args) {
new MyThread("A").start();
new MyThread("B").start();
new MyThread("C").start();
/**
A -> 0
A -> 1
A -> 2
C -> 0
B -> 0
B -> 1
B -> 2
C -> 1
C -> 2
*/
}
}
4 Runnable接口实现多线程
JDK >= 1.8 变为函数式接口
Thread类有单继承局限
class MyThread implements Runnable{
private String name;
public MyThread(String name){
this.name = name;
}
@Override
public void run(){
for (int i =0 ; i< 3; i++) {
System.out.println(this.name + " -> " + i);
}
}
}
class Demo{
public static void main(String[] args) {
Thread t1 = new Thread(new MyThread("A"));
Thread t2 = new Thread(new MyThread("B"));
Thread t3 = new Thread(new MyThread("C"));
t1.start();
t2.start();
t3.start();
/**
A -> 0
A -> 1
A -> 2
C -> 0
B -> 0
B -> 1
C -> 1
C -> 2
B -> 2
*/
}
}
利用Runnable + Lambda实现
class Demo{
public static void main(String[] args) {
for(int i=0; i< 3; i++) {
String name = "对象-" + i ;
Runnable run = ()->{
for(int j=0; j< 3; j++) {
System.out.println(name + "-> " + j);
}
};
new Thread(run).start();
}
/**
对象-0-> 0
对象-0-> 1
对象-0-> 2
对象-1-> 0
对象-2-> 0
对象-1-> 1
对象-1-> 2
对象-2-> 1
对象-2-> 2
*/
}
}
利用Thread + Lambda实现
class Demo{
public static void main(String[] args) {
for(int i=0; i< 3; i++) {
String name = "对象-" + i ;
new Thread(()->{
for(int j=0; j< 3; j++) {
System.out.println(name + "-> " + j);
}
}).start();
}
/**
对象-0-> 0
对象-0-> 1
对象-0-> 2
对象-1-> 0
对象-2-> 0
对象-1-> 1
对象-1-> 2
对象-2-> 1
对象-2-> 2
*/
}
}
多线程优先考虑Runnable 实现,永远都是Thread.start() 启动
5 Thread与Runnable关系
class Thread implements Runnable
Thread 代理类
MyThread implements Runnable 实际业务
使用了代理设计模式
Thread t = new Thread(new MyThread());
Thread类启动多线程调用的是start()方法,而后启动run()方法
Thread类接收Runnable 接口对象,调用start()方法后,会启动Runnable 接口对象的run()方法
多线程实质上在于多个线程可以进行同一资源的抢占
Thread 描述的是线程
Runnable 描述资源
class MyThread implements Runnable{
private int ticket = 5;
public void run() {
while (true){
if(ticket > 0){
System.out.println(ticket-- );
}else{
break;
}
}
}
}
public class Demo {
public static void main(String[] args) {
MyThread t = new MyThread();
Thread t1 = new Thread(t);
Thread t2 = new Thread(t);
Thread t3 = new Thread(t);
t1.start();
t2.start();
t3.start();
/**
* 5
* 3
* 2
* 1
* 4
*/
}
}
6 Callable接口实现多线程
JDK >= 1.5
java.util.concurrent.Callable
@FunctionalInterface
public interface Callable<V> {
V call() throws Exception;
}
继承关系
class Thread implements Runnable
public interface RunnableFuture<V> extends Runnable, Future<V>
public class FutureTask<V> implements RunnableFuture<V> {
import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
import java.util.concurrent.ExecutionException;
class MyThread implements Callable<String>{
public String call() {
return "线程执行完毕";
}
}
public class Demo {
public static void main(String[] args) throws ExecutionException, InterruptedException {
FutureTask<String> task = new FutureTask<String>(new MyThread());
new Thread(task).start();
System.out.println(task.get());
// 线程执行完毕
}
}
区别 Callable Runnable
Runnable JDK1.0 只有run方法,没有返回值
Callable JDK1.5 提供call方法,有返回值
7 多线程运行状态
线程生命周期
创建 start()
就绪
运行 run()
阻塞
终止
第2 章 : 线程常用操作方法
8 线程的命名和取得
获取当前线程对象
public static native Thread currentThread();
线程自动命名,使用 static
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
class MyThread implements Runnable {
public void run() {
System.out.println(Thread.currentThread().getName());
}
}
public class Demo {
public static void main(String[] args) throws ExecutionException, InterruptedException {
MyThread t = new MyThread();
new Thread(t, "线程A").start();
new Thread(t).start();
new Thread(t, "线程B").start();
/**
* 线程A
* 线程B
* Thread-0
*/
}
}
主线程
public static void main(String[] args) throws ExecutionException, InterruptedException {
System.out.println(Thread.currentThread().getName());
// main
}
主线程可以创建若干子线程
主线程控制主体流程
子线程执行耗时操作
9 线程休眠
线程暂缓执行
Exception 必须处理
class InterruptedException extends Exception
public static native void sleep(long millis) throws InterruptedException;
public static void sleep(long millis, int nanos) throws InterruptedException;
休眠线程
public class Demo {
public static void main(String[] args) {
new Thread(()->{
for (int i= 0; i< 3; i++){
System.out.println(i);
// 暂停一秒
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
}
10 线程中断
中断线程执行
public void interrupt()
判断线程是否被中断
public boolean isInterrupted()
所有线程都可以被中断,中断异常必须处理
public class Demo {
public static void main(String[] args) {
Thread t = new Thread(() -> {
// 暂停10秒
try {
Thread.sleep(10 * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
t.start();
if (!t.isInterrupted()) {
t.interrupt();
}
// 抛出异常 sleep interrupted
}
}
11 线程强制运行
线程独占资源,一直到线程执行结束
public final void join() throws InterruptedException
public class Demo {
public static void main(String[] args) {
Thread mainThread = Thread.currentThread();
Thread t = new Thread(() -> {
// 强制执行主线程
try {
mainThread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
for (int i = 0; i < 3; i++) {
System.out.println(Thread.currentThread().getName() + " " + i);
}
});
t.start();
for (int i = 0; i < 3; i++) {
System.out.println(Thread.currentThread().getName() + " " + i);
}
// 抛出异常 sleep interrupted
}
}
12 线程礼让
yield 产生;让步
每一次调用yield()方法只会礼让一次当前的资源
public static native void yield();
public class Demo {
public static void main(String[] args) {
Thread t = new Thread(() -> {
for (int i = 0; i < 30; i++) {
System.out.println("礼让资源");
Thread.yield();
System.out.println(Thread.currentThread().getName() + " " + i);
}
});
t.start();
for (int i = 0; i < 30; i++) {
System.out.println(Thread.currentThread().getName() + " " + i);
}
}
}
13 线程优先级
线程优先级越高,越可能先执行,可能优先抢占到资源
public final int getPriority()
public final void setPriority(int newPriority)
优先级常量
MIN_PRIORITY = 1;
NORM_PRIORITY = 5;
MAX_PRIORITY = 10;
主线程优先级,和默认优先级都是中等优先级 5
public class Demo {
public static void main(String[] args) {
System.out.println(Thread.currentThread().getPriority());
// 5
}
}