黑马程序员之java线程通信学习
来源:互联网 发布:mac怎么一键回到桌面 编辑:程序博客网 时间:2024/05/01 18:44
------- android培训、java培训、期待与您交流! ----------
线程间通信:就是多个线程在操作同一个资源,但是操作的动作不同;等待唤醒机制:wait(),notify(),notifyAll();
都是用在同步中,因为要对持有监视器的线程操作,所以要使用在同步中,因为同步此案有锁。
为什么这些操作线程的方法要定义在Object类中:
停止线程:因为这些方法在操作同步中线程时, 都必须要标识它们所操作线程只有的锁,只有同一个锁上被等待的线程,可以被同一个锁上的notify唤醒,不可以对不同锁中的线程进行唤醒。
原理:结束run方法;
开启多线程运行,运行代码通常都是循环结构;只要控制住循环,就可以让run方法结束,也就是线程结束。Thread的interrupt():强制线程恢复到运行状态,这时会发生异常;
特殊情况:当线程处于冻结状态,就不会读取到标记,那么线程就不会结束。
当制定的方式让冻结的线程恢复到运行状态时,这时需要对冻结进行清除,这么操作会发生异常 ;
强制让线程恢复到运行状态中来,这样就可以操作标记让线程结束,
setDaemon(true/false):将该线程标记为守护线程或用户线程,当正在运行的线程都是守护线程时,Java虚拟机退出;该方法必须在启动线程前调用;
join():当A线程执行到了B线程的.join()方法时,A就会等待.等待B线程都执行完,A才会执行;join可以用来临时加入线程执行。setPriority([1-10]):设置线程的优先级
练习1:使用等待唤醒机制,交叉执行输入输出
class Person{private String name;
private String sex;
private boolean flag = false;
public synchronized void set(String name,String sex){
if(flag)//当有两个以上输入和两个以上输出时用while判断标记,唤醒使用notifyAll()try{r.wait();}catch(Exception e){}this.name = name;this.sex = sex;flag = true;this.notify();
}
public synchronized void get(){
}if(!flag)try{r.wait();}catch(Exception e){}System.out.println(this.name+":"+this.sex);flag = false;this.notify();}
class Input implements Runnable{
private Person r;
Input(Person r){
this.r = r;
}
public void run(){
int x = 0;while(true){
if(x==0){
r.set("mike","man");
}else{
r.set("丽丽","女");
}x = (x+1)%2;
}
}}
class Output implements Runnable{
private Person r;
Output(Person r){
this.r = r;
}
public void run(){
while(true){
r.get();
}
}}
class IODemo{
public static void main(String[] args){
Person p = new Person();Input in = new Input(p);Output out = new Output(p);new Thread(in).start();new Thread(out).start();
}}
练习2:
JDK1.5中提供了多线程升级解决方案,
将同步synchronized替换成了Lock操作;
将Object中wait和notify、notifyAll替换成Condition对象,该对象可以Lock(锁)进行获取(lock.newCondition())。
在该示例中实现了本方只换醒对方操作await(),signal()。
注意:unlock释放锁的动作一定要执行(一般放在finally中)
import java.util.concurrent.locks.*;
class IODemo2{
public static void main(String[] args){
Person p = new Person();Input in = new Input(p);Output out = new Output(p);new Thread(in).start();new Thread(in).start();new Thread(out).start();new Thread(out).start();
}}
class Person{
private String name;
private String sex;
private int count = 1;
private boolean flag = false;
private Lock lock = new ReentrantLock();
private Condition condition_pro = lock.newCondition();
private Condition condition_con = lock.newCondition();
public void set(String name) throws InterruptedException{
lock.lock();try{
while(flag)
condition_pro.await();
this.name = name;this.sex = sex;System.out.println(this.name+":"+this.count++);flag = true;condition_con.signal();
}finally{
lock.unlock();
}
}
public void get() throws InterruptedException{
lock.lock();try{
while(!flag)
condition_con.await();
System.out.println("---"+this.name+":"+this.count);flag = false;condition_pro.signal();
}finally{
lock.unlock();
}
}}
class Input implements Runnable{
private Person r;
Input(Person r){
this.r = r;
}
public void run(){
while(true){
try{
r.set(Thread.currentThread().getName());
}
catch(Exception e){
}
}
}}
class Output implements Runnable{
private Person r;
Output(Person r){
this.r = r;
}
public void run(){
while(true){
try{r.get();}catch(Exception e){}
}
}}
练习3:将线程用setDaemon方法设置成守护线程
class DaemonThread implements Runnable{
private boolean flag = true;
public void run(){
while(flag){
System.out.println(Thread.currentThread().getName()+"...run");
}
}}
class MainClass{
public static void main(String[] args){
DaemonThread dt = new DaemonThread();Thread t1 = new Thread(dt);Thread t2 = new Thread(dt);t1.setDaemon(true);//必须在线程启动前设置t2.setDaemon(true);t1.start();t2.start();int num = 0;while(true){
if(num++ == 60)break;System.out.println(Thread.currentThread().getName()+"..."+num);
}System.out.println("over");
}}
练习4:join方法练习,申请该线程加入到CPU运行中来,
class Demo implements Runnable{
public void run(){
for(int i=0;i<100;i++){
System.out.println(Thread.currentThread().getName()+"..."+i);
}
}}
class JoinDemo{
public static void main(String[] args) throws Exception{
Demo d = new Demo();Thread t1 = new Thread(d);Thread t2 = new Thread(d);t1.start();t1.join();//此时主线程处于冻结状态,直到t1执行结束唤醒主线程;t2.start();//t1.join();//此时有t1,t2两个线程同时存在,他俩交替执行,知道t1结束,再唤醒主线程(不用考虑t2是否执行结束);for(int i = 0;i<100;i++){
System.out.println("main..."+i);
}System.out.println("over");
}}
------- android培训、java培训、期待与您交流! ----------
0 0
- 黑马程序员之java线程通信学习
- 黑马程序员 Java学习总结之同步、线程间通信
- 黑马程序员-java学习之线程
- 黑马程序员:JAVA线程间的通信
- 黑马程序员 【】java学习之路——线程
- 黑马程序员之移动通信分析学习
- 黑马程序员—11—java基础:有关线程通信的学习笔记和学习心得体会
- 黑马程序员——Java多线程线程间通信之Lock的应用
- 黑马程序员 ---- 线程间通信
- 黑马程序员_多线程的线程间通信学习笔记
- 黑马程序员-java学习之多线程技术
- 黑马程序员------java学习笔记之多线程
- 黑马程序员-java学习之多线程
- 黑马程序员---java学习笔记之多线程
- 黑马程序员-----java线程学习与总结
- 黑马程序员 java学习笔记 Day2:线程
- 黑马程序员-Java学习06-线程1
- 黑马程序员-Java学习笔记之多线程
- .net环境下,服务器端运行Javascript
- 文件操作
- 自己动手编写一个VS插件(八)
- linux 高端内存映射方式
- inet_pton函数 和inet_ntop函数
- 黑马程序员之java线程通信学习
- Ubuntu安装配置JDK
- windows下安装RabbitMQ消息服务器
- 循序渐进企业级搜索引擎之Master模块设计及实现-系统请求响应封装模块
- Model1模式案例简单的计算器
- 属性的自动实现(Auto-Implemented Properties) - VS2005
- Shopping Cart page
- hadoop2.2.0 单节点安装 -翻译自hadoop官方文档-与原文有出入
- 一个和会计李菊iioio