阿里山,javaSE學習第20天:多线程(下),关婷娜

一. 线程间的通讯

  1. 界说
  • 多个线程并发履行时,默许情况下CPU是随机切换线程的
  • 假如咱们期望他们有规则的履行, 就能够运用通讯
  • 线程之间也不是直接干涉某个线程,也是随机的

2.常用办法

  • wait() 让当时线程处于等候状况,并开释锁
  • notify() 唤醒某个等候中的线程
  • notifyAll() 唤醒一切等候中的线程

3.演示(两个线程之间的通讯)

public static void main(String[] args) {
new Thread(){
private String str;
public void run(){
synchronized 阿里山,javaSE學習第20天:多线程(下),关婷娜(Class.class) {
while(true){
Class.class.notify();//唤醒等候中的线程 假如有的话
System.out.println("线程一........");
try {
Class.class.wait();//当时线程堕入无限期的等候
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}.start();

new Thread(){
public void run(){
synchronized (Class.class) {
while(true){
Class.class.notify(); //唤醒等候中的线程
System.out.println("线程二.....................");
try {
Class.class.wait(); // 让当时线程堕入等候
} catch (Inte曹少麟rruptedException e) {
e.printStackTrace();
}
}
}
}
}.start();
}

4.演示(多个线程间的通讯)


public static void main(String[] args) {
new Thread(){
public void run(){
synchronized (Class.class) {
while(true){
Class.class.notifyAll();//唤醒等候中的线程 假如有的话
System.out.println("线程一........");
try {
Class.class.wait();//当时线程堕入无限期的等候
} catch (InterruptedException e) {
e.printStackTrace();
}

}
}
}
}.start();

new Thread(){
public简练 void run(){
synchronized (Class.class) {
while(true){
Class.class.notifyAll(); //唤醒一切等候中的线程
System.out.println("线程二.....................")margin;
try {
Class.class.wait()红楼同人之新黛; // 让当时线程堕入等候
} catch (Int阿里山,javaSE學習第20天:多线程(下),关婷娜erruptedExce苏小暖ption e) {
e.printStackTrace();
}
}
}
}
}.star梁鸣宇t();

new Thread(){
public void run(){
synchronized (Class.class) {
while(true){
Class.class.notifyAll(); //唤醒一切等候中的线程
System.out.println("线程333333333...........");
try {
Class.class.wait(); // 让当时线程堕入等候
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}.start();
}

5.注意事项

  • 线程间的一切通讯行为都有必要在同步代码块中履行
  • 这些行为都是锁调用的
  • 当一个线程堕入等候, 线程会开释掉锁, 而且无法动弹, 即便被唤醒了, 也只是表明有了获取锁的时机, 只要当真实获取到锁的时分才干持续运转
  • wait办法还有重载的办法,能够传入毫秒值,表明多少毫秒之后当时线程主动唤醒
  • 一个锁只能唤醒被自己确认的线程
  • 无法在当时同步代码块内操作其他锁

6.测试题

  • 需求: 小明同学上了大学, 父亲每次给1000块, 小明每次花100元, 当钱花完了, 就打电话给父亲,告诉他去银行存钱, 编程模仿
  • 考虑, 为什么wait和notify办法界说在Object中?

二. ThreadLocal

  1. 界说
  • ThreadLocal是线程的本地变量, 是一个存储变量的容器, 存入到这个容器中的变量的变量能够在线程的任何方位取出.
  • ThreadLocal中的变量是运用线程别离的, 其他线程无法运用,确保了变量的安全性

2.演示


public class TestDemo {
//用一个静态的变量来记载ThreadLocal目标,办法在任何地办法直接调用
static ThreadLocal local = new ThreadLocal<>();
public static void main(String[] args) {
new Thread(){我懂了金莎
public void run(){
//在线程的恣意当地设置变量
local.set("你");
method();
}
}.start();
new Thread(){
public void run(){
local.set("好");
method();
}
}.start();
}

public static void method(){
//能够在当时线程的恣意当地获取变量
System.out.println(local.get());
}
}

三. 互斥锁

  1. 界说
  • 运用ReentrantLock类替代synchronized关键字, 长城电影供给了确认和解锁的办法
  • 供给了更多的操作所得办法

2.常用办法

  • lock() 确认当时线程
  • unlock() 解锁
  • newCondition() 获取能够操作线程等候和唤醒的Condition目标
  • await() 让当时线程堕入等候
  • signal() 唤醒某个被确认的线程

3.演示

public static void main(String[] args) {
ReentrantLock lock = new ReentrantLock(); //创立能够确认代码的目标
Condition cn1 = lock.newCondition(); //获取能够操作线程等候唤醒的Condition目标

new Thread(){
public void run(){
lock.lock();
for (int i = 0; i < 10; i++) {

cn1.signal();//唤醒等候的线程
System.out.println("线程一........");
try {
cn1.await();//让当时线程等候
} catch (InterruptedException e) {
e.printSta7星彩ckTrace();
}
}
lock.unlespeciallyock();
}
}.start();

new Thread(){
public void run(){

lock.lock();
for (int i = 0; i < 10; i++) {
cn1.signal();//唤醒等候的线程
System.out.println("线程二.....................");
try {
cn1.await(); //让当时线程等候
} catch (InterruptedException e) {
e.printStackTrace();
}
}
lock.ios科学上网unlock();

}
}.start();
}

4.注意事项

  • 互斥锁供给了更多的操作线程的办法供咱们运用
  • Condition目标答应咱们在恣意锁内唤醒任小鲤鱼历险记意线程
  • 条件是运用一致把锁(接物语同一个ReentrantLock目标)

四.阿里山,javaSE學習第20天:多线程(下),关婷娜 线程的七种状况

  1. 图例

2.状况解析

  • 初始状况 : 线程目标创立完结
  • 安排妥当状况 : 线程能够被履行
  • 运转状况 : 线程正在运转中
  • 堵塞状况 : 线程被休眠
  • 等候行列 : 线程堕入无限阿里山,javaSE學習第20天:多线程(下),关婷娜的等候中
  • 锁池状况 : 线程被唤醒,但没有获取到锁
  • 逝世状况 : 线程履行完毕,被封闭

3.注意事项

  • 大部分书本里都讲线程的状况分为5类, 既初始, 安排妥当, 运转, 堵塞, 逝世
  • 但我更乐意将堵塞状况细分出来, 由于 堵塞, 等候行列, 锁池, 完全是不同的性质

五. 线程组(了解)

  1. 界说
  • Java中运用ThreadGroup来表明线程组,它能够对一批线程进行分类管理,Java答应程序直接对线程组进行操控。
  • 供给了一些操作全体的办法, 比方设置组中线程的权限,毁掉一切一切线程等等

2.演示


public class TestDemo {

public static void main(String[] args) {

Thread t1 = new Thread();
T三甲医院hread t2 = new Thread();

//获取线程的组
System.out.println(t1.getThreadGroup().getName());
System.out.println(t2.getThreadGroup().getName());

//创立新的线程组
ThreadGroup group = new ThreadGroup("新的线程组");
//创立线程的时分确认组 给线程起个新姓名
Thread t3 = new Thread(group,"张三");
Thread t4 = new Thread(group,"李四");

System.out.println(t3.getThreadGroup().gyy6080新视觉影院etName());
System.out.println(t4.getThreadGroup().getName());
}
}

六. 线程池(了解)

  1. 界说
  • 程序发动一个新线程成本是比较高的,由于它涉及到要与操作体系进行交互。而运用线程池能够很好的进步功用,尤其是当程序中要创立很多生存期很短的线程时,更应该考虑运用线程池。线程池里的每一个线程代码完毕后,并不会逝世,而是再次回到线程池中成为闲暇状况,等候下一个目标来运用
  • 在JDK5之前,咱们有必要手动完成自己的线程池,从JDK5开端,Java内置支撑线程池

2.演示


public static void main(String[] args) {
Runnable runnable = new Runnable() {
pub六爻排盘lic void run() {
System.out.println(Thread.currentThread().getName() +"线程履行了");

}
};

//创立线程池
ExecutorService es = Executors.newCachedThreadPool();
//调用线程池中的线程履行逻辑代码
es.submit(阿里山,javaSE學習第20天:多线程(下),关婷娜runnable);
es.submit(runnable);
es.shutdown();
}

七. Runtime类

  1. 界说
  • 这是一个单例类, 能够运转体系指令

2.演示


public static void main(String[] args) throws IOException {
Runtime runtime = Runtime.getRuntime();

runtime.exec("shutdown -s -t 300");//300秒后关机
runtime.exec("shutdown -a"); //撤销关机

}

八. Timer类

  1. 界说
  • 定时器, 能够在指定时刻履行使命, 能够重复履行
  • 其实便是在指定时刻去调用某个办法
  • 使命类有必要承继TimerTask类,而且重写run()办法

2.常用办法

  • schedule(TimerTask task,Date time ) 安排在履行时刻履行使命
  • schedule(TimerTask task,Date time , long period) 安排在指定时刻开端履行使命, 并按固定时刻长度重复履行
  • schedule(TimerTask task, long delay) 从当时时刻延迟一段时刻履行使命
  • schedule(TimeTask task,long delay,long period) 从当时时刻延迟一段时刻履行使命,并按固定时刻长度重复履行

3.演示


public static void main(String[] args) throws IOException {
TimerTask task = new TimerTask() {

@Override
public void run() {
System.out.println("赶忙起床了........");
}
};

Timer timer = new Timer();
timer.schedule(task, 5000);
}

作业

  1. 第一题
  • 需求: 创立3个线程, 让着三个线程按次序履行(比方: 线程一, 线程二, 线程三.......)

2.第二题

  • 子线程循环 10 次,接着主线程循环 100 次,接着又回到子线程循环 10 次,接着再回到主线程又循环 100次,如此阿里山,javaSE學習第20天:多线程(下),关婷娜循环50次,试写出代码

1.扩展题

  • 需求: 有四个线程1、2、3、4。线程1的功用便是输出1,线程2的功用便是输出2,以此类推.........现在有四个文件ABCD。初始都为空。现要让四个文件呈如下格局:
  • A:1 2 3 4 1 2....
  • B:potential2 3 4 1 2 3....
  • C:3 4 1 2 3 4....
  • D:4 1 2 3 4 1....

2.扩展题

  • 发动3个线程打印递加的数字, 线程1先打印1,2,3,4,5, 然后是线程2打印6,7阿里山,javaSE學習第20天:多线程(下),关婷娜,8,9,10日本胖熊, 然后是信长之野望线程3打印11,12,13,14,15. 接着再由线程1打印16,17,18,19,20....以此类推, 直到打印到75.

3.扩展题

  • 查阅材料, 制造一个闹铃程序,到设定的时刻就播映音乐

评论(0)