黑马程序员——线程间的通讯
来源:互联网 发布:从python开始学编程pdf 编辑:程序博客网 时间:2024/04/30 14:37
-------android培训、java培训、期待与您交流! ----------
一、
/*
线程间通讯:其实就是多个线程在操作同一个资源,但是操作动作不同。
*/
class Res
{
privateString name;
privateString sex;
privateboolean flag = false;
}
class Input implements Runnable
{
private Res r;
Input(Res r)
{
this.r = r;
}
public void run()
{
int x = 0;
while(true)
{
synchronized(r)//同步的两个线程要用同一个锁,r是程序中的唯一对象
{
if(r.flag)
try{r.wait();}catch(Exceptione){}
/*线程必须拥有锁才能wait(),所以wait()必须使用在同步中。必须要标识wait()操作的线程所属的锁(obj.wait()),notify()也要标识*/
if(x==0)
{
r.name="mike";
r.sex="man";
}
else
{
r.name="丽丽";
r.sex="女";
}
x = (x+1)%2;
r.flag = true;
r.notify();
}
}
}
}
/*
线程运行时,内存会建立一个线程池,等待线程都存在线程池当中,当notify()时唤醒的都是线程池中的线程,当线程池中有多个等待线程时,notify()唤醒的是的一个被等待的线程。
*/
class Output implements Runnable
{
private Res r;
Output(Res r)
{
this.r = r;
}
public void run()
{
while(true)
{
synchronized(r)
{
if(!r.flag)
try{r.wait();}catch(Exceptione){}
System.out.println(r.name+"......"+r.sex);
r.flag = false;
r.notify();
}
}
}
}
class InputOutputDemo
{
public static void main(String[]args)
{
Res r = new Res();
Input in = new Input(r);
Output out = new Output(r);
Thread t1 = new Thread(in);
Thread t2 = new Thread(out);
t1.start();
t2.start();
}
}
/*
wait(),notify(),notifyAll()用来操作线程为什么定义在了Object类中?
这些方法存在于同步中
使用这些方法时必须要标识所属的同步锁
锁可以使任意对象,所以任意对象调用的方法一定定义在Object中
wait(),sleep()有什么区别?
wait()释放资源、释放锁
sleep()释放资源、不释放锁
只有同一个锁上的被等待线程,可以被同一个锁上的notify()唤醒,不可以对不同锁中的线程进行唤醒
*/
二、
/*
对于多个生产者和消费者。为什么要定义while判断标记
原因:让被唤醒的线程再一次判断标记。
为什么定义notifyAll
因为需要唤醒对方线程。因为只用notify,容易出现只唤醒本方线程的情况,导致程序中的所有线程都等待。
*/
class ProducerConsumerDemo
{
public static void main(String[]args)
{
Resource r = new Resource();
Producer pro = newProducer(r);
Consumer con = newConsumer(r);
Thread t1 = new Thread(pro);
Thread t2 = new Thread(pro);
Thread t3 = new Thread(con);
Thread t4 = new Thread(con);
t1.start();
t2.start();
t3.start();
t4.start();
}
}
class Resource
{
private String name;
private int count = 1;
private boolean flag = false;
public synchronized voidset(String name)
{
while(flag)//多个生产者消费者的时候,要循环判断标记
try{this.wait();}catch(Exceptione){}
this.name =name+"---"+count++;
System.out.println(Thread.currentThread().getName()+"...生产者..."+this.name);
flag = true;
this.notifyAll();//当循环判断标记时,容易全部等待,所以要唤醒全部
}
public synchronized void out()
{
while(!flag)
try{wait();}catch(Exceptione){}
System.out.println(Thread.currentThread().getName()+"...消费者..."+this.name);
flag = false;
this.notifyAll();
}
}
class Producer implements Runnable
{
private Resource res;
Producer(Resource res)
{
this.res = res;
}
publicvoid run()
{
while(true)
{
res.set("+商品+");
}
}
}
class Consumer implements Runnable
{
private Resource res;
Consumer(Resource res)
{
this.res = res;
}
public void run()
{
while(true)
{
res.out();
}
}
}
三、
/*
JDK1.5中提供了多线程升级解决方案。将同步synchronzied替换成显示Lock操作。将Object中的wait,notify,notifyAll,替换了Condition对象。该对象可以Lock锁,进行获取。
包java.util.concurrent.locks
接口 Lock 实现提供了比使用synchronized方法和语句获得的更广泛的锁定操作,
支持Condition
方法lock() 获取锁
unlock() 释放锁
接口 Condition将Object监视器方法分解成截然不同的对象,与Lock实现组合使用。
Lock替代了synchronized方法和语句的使用,Condition替代了
Object监视器方法的使用
方法 await()等待
Signal() 唤醒一个
signalAll() 全唤醒
该示例中,实现了本方唤醒对方的操作。
*/
importjava.util.concurrent.locks.*;
class ProducerConsumerDemo2
{
public static void main(String[] args)
{
Resource r = new Resource();
Producer pro = new Producer(r);
Consumer con = new Consumer(r);
Thread t1 = new Thread(pro);
Thread t2 = new Thread(pro);
Thread t3 = new Thread(con);
Thread t4 = new Thread(con);
t1.start();
t2.start();
t3.start();
t4.start();
}
}
class Resource
{
private String name;
private int count = 1;
private boolean flag = false;
private Lock lock = newReentrantLock();//创建锁对象
private Condition condition_pro =lock.newCondition();//生产者的锁
private Condition condition_con =lock.newCondition();//消费者的锁
public void set(Stringname)throws InterruptedException
{
lock.lock();//加锁
try
{
while(flag)
condition_pro.await();//等待(本方)
this.name =name+"---"+count++;
System.out.println(Thread.currentThread().getName()+"...生产者..."+this.name);
flag = true;
condition_con.signal();//唤醒(对方)
}
finally
{
lock.unlock();//释放锁的动作一定要执行。
}
}
public void out()throwsInterruptedException
{
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 Resource res;
Producer(Resource res)
{
this.res = res;
}
public void run()
{
while(true)
{
try
{
res.set("+商品+");
}
catch(InterruptedException e)
{ }
}
}
}
class Consumer implements Runnable
{
private Resource res;
Consumer(Resource res)
{
this.res = res;
}
public void run()
{
while(true)
{
try
{
res.out();
}
catch(InterruptedException e)
{ }
}
}
}
四、
/*
stop方法已经过时。如何停止线程呢?只有一种,run方法结束。开启多线程运行,运行代码通常是循环结构。只要控制住循环,就可以让run方法结束,也就是线程结束。
特殊情况:当线程出于了冻结状态就不会读取到标记,那么线程就不会结束。
当没有指定方式让冻结的线程恢复到运行状态时,这是需要对冻结进行清除。
强制让线程恢复到运行状态中来,这样就可以操作标记让线程结束。
Thread类提供该方法 interrupt();
setDaemon(boolean):守护线程。标记为真时,该线程则为守护线程。
该方法必须在启动线程前调用,当前台线程都运行完,只剩下守护线程是,则jvm退出。
*/
class StopThread implements Runnable
{
private boolean 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");
}
}
public void changeFlag()
{
flag = false;
}
}
class StopThreadDemo
{
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)
{
//st.changeFlag();
//t1.interrupt();
//t2.interrupt();
break;
}
System.out.println(Thread.currentThread().getName()+"......"+num);
}
System.out.println("over");
}
}
五、
/*
join:
当A线程执行到了B线程的 join() 方法时,A就会等待,等待B线程执行完,A才会执行,join可以用来临时加入线程执行。
toString()方法,返回该线程的字符串表示形式,包括线程名称、优先级和线程组
优先级:线程抢资源的频率,一共有十级,所有线程默认优先级为5.
setPriority(int newPriority)
static int MAX_PRIORITY
线程可以具有的最高优先级。10
static int MIN_PRIORITY
线程可以具有的最低优先级。1
static int NORM_PRIORITY
分配给线程的默认优先级。5
static void yield()
暂停当前正在执行的线程对象,并执行其他线程。
临时停止
*/
class Demo implements Runnable
{
public void run()
{
for(int x=0; x<70; x++)
{
System.out.println(Thread.currentThread().toString()+"..."+x);
Thread,yield();//执行到此的线程暂时释放执行权。
}
}
}
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.setPriority(Thread.MAX_PRIORITY);//设置最大优先级。
//t1.join();
t2.start();
for(int x=0; x<80; x++)
{
System.out.println("main..."+x);
}
System.out.println("over");
}
}
六、
/*
开发时常用写法,采用匿名内部类的形式
*/
class ThreadTest
{
public static void main(String[] args)
{
new Thread()
{
public void run()
{
for(int x=0; x<100; x++)
{
System.out.println(Thread.currentThread().getName()+"..."+x);
}
}
}.start();
for(int x=0; x<100; x++)
{
System.out.println(Thread.currentThread().getName()+"..."+x);
}
Runnable r = new Runnable()
{
public void run()
{
for(int x=0; x<100; x++)
{
System.out.println(Thread.currentThread().getName()+"..."+x);
}
}
};
new Thread(r).start();
}
}
-------android培训、java培训、期待与您交流! ----------
- 黑马程序员——线程间的通讯
- 黑马程序员——JAVA基础之多线程的线程间通讯等
- 黑马程序员笔记——Java多线程线程间通讯
- 黑马程序员—JAVA线程间通讯问题
- 黑马程序员--线程间通讯
- 黑马程序员---线程间通讯
- 黑马程序员 线程通讯——唤醒的线程需要再次进行标记值判断
- 黑马程序员---线程间通讯的两个例子
- 黑马程序员-java基础-线程间的通讯问题
- 34.黑马程序员-线程间通讯
- 黑马程序员——多线程--线程间的通讯及安全问题和JDK1.5的新特性
- 黑马程序员——【学习笔记】多线程——线程间通讯
- 黑马程序员—线程
- 黑马程序员 — 线程
- 黑马程序员_线程间的通讯和生产者和消费者之间的问题
- 黑马程序员_JAVA笔记12——多线程间通讯
- 黑马程序员——线程的知识
- 黑马程序员——线程的学习
- ./runInstaller: /download/database/install/.oui: /lib/ld-linux.so.2: bad ELF interpreter: No such fi
- 小白_最近浏览功能
- 统计静态库的代码数据大小
- 书籍零食 ---1
- PHP使用Memcached
- 黑马程序员——线程间的通讯
- Java注解annotation : invalid type of annotation member
- django数据库相关操作
- 一个备份MySQL数据库的简单Shell脚本
- iOS整理 -- 多线程之NSThread
- 高德地图key值错误,百思不得解的问题暂时解决办法。
- Android ScroolView不能撑满全屏的问题
- openSession和getCurrentSession
- 开发记录.