视频基础之线程通讯
来源:互联网 发布:逛淘宝网 编辑:程序博客网 时间:2024/06/08 14:58
一、线程间通讯:
多个线程在操作同一个资源,但是操作的动作不同。
wait()-------notify( )---notifyAll( ) 都使用在同步中,因为要对持有监视器(锁)的线程操作。所以要使用在同步中,因为只有同步才有锁。
1、为什么这线程的方法定义在Object类中呢?
因为这些方法在操作同步线程时,都必须标识他们所操作线程只有的锁,只有同一个锁上的被等待线程,才可以被同一个锁上notify所唤醒。不可以对不同锁中的线程进行唤醒,也就是说等待和唤醒必须是同一把锁。
而锁可以是任意对象,所以可以被任意对象调用的方法定义在Object类中。
2、wait( )是一个方法,隶属于Object类
用法:publicvoid wait( ){throw new Exception( )}
在此处无法throw 只能try
二、生产者和消费者
需求:多个生产者和多个消费者,生产者生产商品,消费者消费商品
任意一个生产者生产一次,则任意一个消费者消费一次,交替进行;
思路:1、定义一个操作资源,生产者和消费者对其进行操作
其中包括两个构造函数:生产商品和消费商品
2、定义生产者实现Runnable接口以便多线程
3、定义消费者实现Runnable接口以便实现多线程、
4、创建主函数,建立两个生产者和两个消费者
class Resource{ private String name; //声明一个name private int count=1; //初始化序号 private Boolean flag=false; //初始化标记为假 public synchronized voidset(String name) //闯进生产商品构造函数 {while(flag) //判断标记是否为真,若为真则在此等待标记为假的对象运行,唤醒后判断标记 try{this.wait();}catch(Exception e){ } //等待函数this.name=name+”….”+count++; //商品名称加序号赋值给本类声明的nameSystem.out.println(Thread.currentThread().getName()+“..生产者..”+this.name);//获取正在执行线程对象名称加我们自定义的商品名称flag=true;//商品生产完成将标记更改为真this.notifyAll( );//唤醒所有正在等待的进程,}publicsynchronized void out( ) //{ while(!flag) try{this.wait( );}catch(Exception e){ } System.out.println(Thread.currentThread().getName()+”..消费者…….”+this.name); flag=false; this.notifyAll( );}}class Producer implements Runnable //创建生产者类{ private Resourse res; //声明Resource类的res Producer(Resouece res){ this.res=res;}public void run() //创建线程,复写runnable中的run函数{ while(true) { res.set(“商品”);//调用res对象中的set函数}}}class Consumer implements Runnable//穿件消费者类{ Private Resource res; Consumer (Resource res) { this.res=res;}public voidrun(){ while(true) { res.out();}}}class ResourceDemo{ public static voidmain(String[ ] args) //主函数 {Resource r=new Resource();//创建资源对象Producer p=new Producer(r);//创建生产者对象Consumer c=new Consumer(r);//创建消费者对象Thread p1=new Thread(p);Thread p2=new Thread(p);Thread c1=new Thread(c);Thread c2=new Thread(c);p1.start();p2.start();c1.start();c2.start();}}
1、为什么要定义while判断标记呢?
因为让被唤醒的线程再一次判断标记
2、为什么定义notifyAll?
因为需要唤醒对方的线程。如果用notify容易出现只唤醒本线程的情况,导致程序中的所有线程都在等待。
三、1.5版本后提供了锁对象以及等待挂起封装函数
1、将同步synchroized替换成现实lock操作
2、将Object中的wait,notifyAll替换成了condition对象,该对象可以lock锁进行获取
3、在该实例中,实现了本方只唤醒对方的操作;
import java.util.concurrent.locks.*;//引入locks包
class Resource
{
private String name; //声明一个name
private int count=1; //初始化序号
private Boolean flag=false; //初始化标记为假
privateLock lock=new ReentrantLock(); //使用解锁函数建立对象
private Condition condition_pro=lock.newCondition();//建立等待解除等待对象
privateCondition condition_con=lock.newCondition();
public void set(String name) throws InterruptedException //await是抛出异常结构
{
lock.lock();//调用锁,锁住
try
{
while(flag)
condition_pro.await();//抛出异常,没有try因此要throws
this.name=name+”….”+count++; //商品名称加序号赋值给本类声明的name
System.out.println(Thread.currentThread().getName()+“..生产者..”+this.name);
flag=true;//商品生产完成将标记更改为真
condition_con.signal();//唤醒对方condition_con线程
}
finally
{
lock.unlock();//解除本锁
}
}
public void out( ) throws InterruptedException //
{
lock.lock();
try
{
while(!flag)
condition_con.await();
System.out.println(Thread.currentThread().getName()+”..消费者…….”+this.name);
flag=false;
condition_pro.signal();
}
finally
{
lock.unlock();
}
}
}
class Producer implements Runnable //创建生产者类
{
private Resourse res; //声明Resource类的res
Producer(Resouece res)
{
this.res=res;
}
public void run( ) //创建线程,复写runnable中的run函数
{
while(true)
{
try
{
res.set(“商品”);//调用res对象中的set函数
}
catch(InterruptedExceptione)
{}
}
}
}
class Consumer implements Runnable//穿件消费者类
{
Private Resource res;
Consumer (Resource res)
{
this.res=res;
}
public void run()
{
while(true)
{
try
{
res.out();
}
catch(InterruptedExceptione)
{}
}
}
}
class ResourceDemo
{
public static void main(String[ ] args) //主函数
{
Resource r=new Resource();//创建资源对象
Producer p=new Producer(r);//创建生产者对象
Consumer c=new Consumer(r);//创建消费者对象
Thread p1=new Thread(p);
Thread p2=new Thread(p);
Thread c1=new Thread(c);
Thread c2=new Thread(c);
p1.start();
p2.start();
c1.start();
c2.start();
}
}
四、线程结束
线程的结束之前使用stop方法,现在已经过时,使用另一种run方法结束。
思路:开启多线程运行,运行代码通常是循环结构,只要能够控制住循环,就可以让run方法结束,也就是线程结束。
特殊情况:当线程处于冻结状态,就不会读取到标记,程序就不会结束。
class StopThread implements Runnable
{
private booleas flag=true;
public synchronized void run()
{
while(flag)
{
try
{
wait();
}
catch(InterruptedException e)
{
System.out.println(Thread.currentThread().getName()+”…Exception”);
flag=false;//对冻结进行清除
}
System.out.println(Thread.currentThread().getName()+”..run”);
}
}
}
class StopThreadDemo
{
public static void main(String[] args)
{
StopThreadst=new StopThread();
Thread t1=newThread(st);
Thread t2=newThread(st);
t1.start();
t2.start();
int num=0;
while(true)
{
if(num++=60)
{
t1.interrupt();//对冻结进行解除
t2.interrupt();
}
System.out.println(Thread.currentThread().getName()+”…..”+num);
}
System.out.println(“over”);
}
}
当没有指定的方式让冻结的线程恢复到运行状态,这时需要对冻结进行清除。强制让线程恢复到运行状态中来,这样就可以操作标记让线程结束
Thread类提供该方法interrupt();
五、守护线程(主线程结束该线程结束)
将该线程标记为守护线程或用户线程,当正在运行的线程都是守护线程时,Java退出运行。
该方法必须在启动线程前调用。.setDaemon(true);
class StopThread implements Runnable
{
private Boolean flag=true;
public synchronized void run()
{
while(flag)
System.out.println(Thread.currentThread().getName()+”...run”);
}
class ShouHuDemo
{
public static void main(String[] args)
{
StopThread st=newStopThread();
Thread t1=new Thread(st);
Thread t2=new Thread(st);
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”);
}
}
六、Join函数
主线程让Join线程先运行:join也是一个需要抛或try的构造函数
特点:当A线程执行到了B线程的Join()方法时,就会等待,等B线程都执行完,A才会执行。
Join可用来临时加入线程。
class Demo implements Runnable
{
public void run()
{
for(int x=0;x<70;x++)
System.out.println(Thread.currentThread().getName)+”…”+x);
}
}
class JoinDemo
{
public static void main(String[] args) throws Exception//Join对应函数抛出异常
{
Demo d=new Demo();
Thread d1=new Thread(d);
Thread d2=new Thread(d);
d1.start();
d1.join();//Join函数抢夺执行权,d1结束后主线程在运行
d2.start();
for(int x=0;x<100;x++)
{
System.out.println(Thread.currentThread().getName()+”…..”+x);
}
System.out.println(“over”);
}
}
七、多线程优先级、临时停止
多线程优先级即可理解为抢夺CPU执行权能力的大小,1-10,
10是MAX_PRIORITY
5是NORM_PRIORITY
1是MIN_PRIORITY
调用方式:d1.setPriority(Thread. MAX_PRIORITY);
临时停止: Thread.yield();暂停当前正在执行的线程对象,并执行其他线程
class Demo implements Runnable
{
public void run()
{
for(int x=0;x<70;x++)
{
System.out.println(Thread.currentThread().getName)+”…”+x);
Thread.yield();//临时停止
}
}
}
class YouXianDemo
{
public static void main(String[] args) // throws Exception//Join对应函数抛出异常
{
Demo d=new Demo();
Thread d1=new Thread(d);
Thread d2=new Thread(d);
d1.start();
d1.setPriority(Thread.MAX_PRIORITY);//更改d1的优先级
//d1.join();//Join函数抢夺执行权,d1结束后主线程在运行
d2.start();
for(int x=0;x<100;x++)
{
System.out.println(Thread.currentThread().getName()+”…..”+x);
}
System.out.println(“over”);
}
}
- 视频基础之线程通讯
- 黑马视频-----线程通讯分析(黑马视频)
- 移动互联网实时视频通讯之视频采集
- 移动互联网实时视频通讯之视频采集
- 移动互联网实时视频通讯之视频采集
- 移动互联网实时视频通讯之视频采集
- 移动互联网实时视频通讯之视频采集
- 移动互联网实时视频通讯之视频采集
- 多线程编程之三 线程间通讯
- 线程通讯
- 线程通讯
- 线程基础之产生线程
- Java学习笔记之线程(五):线程的通讯
- 黑马程序元-java基础 线程间通讯
- java基础—线程间的通讯 生产者与消费者
- 黑马程序员-java基础-线程间的通讯问题
- java基础之线程
- Java基础之线程
- jQuery实战笔记(二)-创建元素包装集
- Lucence(Index,Searcher,Analyzer)技术原理整理
- iOS中添加UITapGestureRecognizer手势识别后,UITableView的didSelectRowAtIndexPath失效
- iOS开发数据库篇—2.Sqlite常用语句及功能
- 智捷公开课马上开始了-欢迎大家一起讨论学习-第一系列读《Swift开发指南(修订版) 》看Swift视频教程
- 视频基础之线程通讯
- 浅谈Android五大布局(一)——LinearLayout、FrameLayout和AbsoulteLayout
- 嵌入式系统之实时系统调度算法
- mfc入门资料
- iOS 系统控件显示中文
- OC---Math公式
- 从释迦摩尼到爱因斯坦
- WCF与Webservice的区别
- 借款甹个非官方