Java学习路线-14:多线程编程
第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 */ }
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
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 */ }
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
利用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 */ }
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
利用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 */ }
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
多线程优先考虑Runnable 实现,永远都是Thread.start() 启动
5 Thread与Runnable关系
class Thread implements Runnable
- 1
Thread 代理类
MyThread implements Runnable 实际业务
使用了代理设计模式
Thread t = new Thread(new MyThread());
- 1
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 */ }
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
6 Callable接口实现多线程
JDK >= 1.5
java.util.concurrent.Callable
@FunctionalInterface
public interface Callable<V> { V call() throws Exception;
}
- 1
- 2
- 3
- 4
- 5
继承关系
class Thread implements Runnable
public interface RunnableFuture<V> extends Runnable, Future<V>
public class FutureTask<V> implements RunnableFuture<V> {
- 1
- 2
- 3
- 4
- 5
- 6
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()); // 线程执行完毕 }
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
区别 Callable Runnable
Runnable JDK1.0 只有run方法,没有返回值
Callable JDK1.5 提供call方法,有返回值
7 多线程运行状态
线程生命周期
创建 start()
就绪
运行 run()
阻塞
终止
- 1
- 2
- 3
- 4
- 5
第2 章 : 线程常用操作方法
8 线程的命名和取得
获取当前线程对象
public static native Thread currentThread();
- 1
线程自动命名,使用 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 */ }
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
主线程
public static void main(String[] args) throws ExecutionException, InterruptedException { System.out.println(Thread.currentThread().getName()); // main }
- 1
- 2
- 3
- 4
主线程可以创建若干子线程
主线程控制主体流程
子线程执行耗时操作
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;
- 1
- 2
- 3
- 4
休眠线程
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(); }
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
10 线程中断
中断线程执行
public void interrupt()
- 1
判断线程是否被中断
public boolean isInterrupted()
- 1
所有线程都可以被中断,中断异常必须处理
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 }
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
11 线程强制运行
线程独占资源,一直到线程执行结束
public final void join() throws InterruptedException
- 1
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 }
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
12 线程礼让
yield 产生;让步
每一次调用yield()方法只会礼让一次当前的资源
public static native void yield();
- 1
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); } }
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
13 线程优先级
线程优先级越高,越可能先执行,可能优先抢占到资源
public final int getPriority()
public final void setPriority(int newPriority)
- 1
- 2
- 3
优先级常量
MIN_PRIORITY = 1;
NORM_PRIORITY = 5;
MAX_PRIORITY = 10;
- 1
- 2
- 3
主线程优先级,和默认优先级都是中等优先级 5
public class Demo { public static void main(String[] args) { System.out.println(Thread.currentThread().getPriority()); // 5 }
}
- 1
- 2
- 3
- 4
- 5
- 6
文章来源: pengshiyu.blog.csdn.net,作者:彭世瑜,版权归原作者所有,如需转载,请联系作者。
原文链接:pengshiyu.blog.csdn.net/article/details/103059779
- 点赞
- 收藏
- 关注作者
评论(0)