线程间通信学习笔记
来源:互联网 发布:手机电池修复软件下载 编辑:程序博客网 时间:2024/05/16 02:24
注:通过网上学习资料整理的笔记
在一个多线程的应用程序中,所有线程共享进程资源,协同工作。所以,线程之间的通信是编写多线程应用的必不可少的环节。
线程之间的通信包括互斥、同步等,它是多线程设计中最难控制的部分,也是关键部分。
实例:两个线程,一个是设置学生属性,另一个获取学生属性。
类似生产者和消费者。
1 学生类
2 测试类
3 设置学生的属性类
4 获取学生的属性类
问题:
只有次数多才使用线程,使用了循环,数据出现了错误。
线程安全问题:
1 有共享数据 s
2 被多个线程调用 设置和获取线程
3 共享数据被多条语句使用 s.name和s.age;
如何解决线程安全问题?
同步代码块
如何找到共享的代码块?
共享数据被多条语句操作的代码。
注意:
加锁必须对多个多个线程加锁,只加一部分没用。
多个线程间必须是同一把锁
目前为止,解决了线程安全问题,数据一出一大片,我们想交替出现,如果没设置能获取吗?不能
为了保证数据的交替出现,java使用等待唤醒机制
* wait()
* notify()
* notifyAll()
* 等待唤醒机制一般使用在同步中
* 举例:
* 抓人游戏
代码:
学生类:public class Student { private String name ; private int age; /** * 是否有数据 */ private boolean flag = false; public synchronized void set(String name,int age){ if(this.flag){ try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } this.name = name ; this.age = age; this.flag = true; this.notify(); } public synchronized void get() { if(!this.flag){ try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println(this.name +"****"+ this.age); this.flag = false; this.notify(); }}设置学生属性的线程:public class SetStudent implements Runnable { private Student s; public SetStudent(Student s) { this.s=s; } public void run() { int x = 0; while(true){ if(x%2==0){ s.set("周杰伦", 28); }else{ s.set("刘德华", 40); } x++; } }}获取学生属性的线程:public class GetStudent implements Runnable { private Student s; public GetStudent(Student s) { this.s = s; } public void run() { while(true){ s.get(); } }}测试类:public class StudentTest { public static void main(String[] args) { Student s = new Student(); SetStudent ss = new SetStudent(s); GetStudent gs = new GetStudent(s); Thread t1 = new Thread(ss); Thread t2 = new Thread(gs); t1.start(); t2.start(); }}
以上是使用 synchronized 同步代码解决的。
JDK5出现了Lock接口,可以替代synchronized 同步代码块,使用更方便。
核心部门:
//创建锁private final Lock lock = new ReentrantLock();//Condition 将 Object 监视器方法(wait、notify 和 notifyAll)//分解成截然不同的对象,以便通过将这些对象与任意 Lock 实现组合使用private final Condition condition = lock.newCondition();使用Lock修改的学生类:public class Student { private String name ; private int age; /** * 是否有数据 */ private boolean flag = false; private final Lock lock = new ReentrantLock(); private final Condition condition = lock.newCondition(); public void set(String name,int age){ lock.lock(); if(this.flag){ try { condition.await(); } catch (InterruptedException e) { e.printStackTrace(); } } this.name = name ; this.age = age; this.flag = true; condition.signal(); lock.unlock(); } public void get() { lock.lock(); if(!this.flag){ try { condition.await(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println(this.name +"****"+ this.age); this.flag = false; condition.signal(); lock.unlock(); }}
线程的优先级:setProperty(int x )和getProperty()
更改线程优先级只能在一定程度下多执行下,并不能完全保证。
默认是5,范围1到10
加入线程:join()
等待该线程终止,其他线程都等待加入线程执行完再执行。
等待线程: yield()
暂停当前正在执行的线程对象,并执行其他线程,让线程尽可能的和谐执行,但并不能保证等待唤醒机制的效果。(静态方法)
守护线程:setDaemon(boolean on)
将该线程标记为守护线程或用户线程。当正在运行的线程都是守护线程时,Java 虚拟机退出。如坦克大战。
- 线程间通信学习笔记
- Java学习笔记(线程间通信)
- 进程\线程间通信学习笔记(一)
- 学习笔记之线程间通信
- python学习笔记——线程间通信Event
- 黑马程序员_多线程的线程间通信学习笔记
- Java学习笔记之线程间的通信
- PyQt5学习笔记13----pyqt线程间通信
- Java 学习笔记——线程间通信(day12)
- Linux进程线程学习笔记:进程间通信之 管道
- python学习笔记——线程间通信Event
- Android学习笔记之多线程间的异步通信
- 多线程学习笔记3-线程间的通信(1)
- 多线程学习笔记4-线程间的通信(2)
- 多线程学习笔记1-概念、创建、互斥锁、线程间通信
- PyQt5学习笔记13----pyqt线程间通信
- (48)Java学习笔记——多线程 / 线程间通信 / 线程组 / 线程池 /
- 黑马程序员 学习笔记六:线程间的通信以及通信安全问题
- 207&210. Course Schedule
- 风险管理图与四六级步骤
- 【深入Java虚拟机】之二:Class类文件结构
- java反射
- 【Maven】2、Maven安装
- 线程间通信学习笔记
- mysql函数实现省市的分组
- 如何在命令行程序中运行Java程序
- 不允许创建临时变量,交换两个数的内容
- Collection接口
- 【深入Java虚拟机】之三:类初始化
- 单调递增子序列(二)
- TypeLite (一) -- 安装及使用
- cf 758 B. Blown Garland模拟