进程通信:实质就是两个线程在操控同一个资源,只是操作的动作不同
等待唤醒机制。
先来看两个方法
wait() notify()这样的方法都使用在同步中,因为要对持有监视器(锁)的线程进行操作。而只有同步才有锁。
又由于这些方法在操作同步中的线程时,都必须要标识他们所操作那个线程所持有的锁,以保证等待和唤醒的必须是
同一个锁。而锁可以是任意对象,因此这两个方法定义在Object类中
class Res
{
private String name;
private String sex;
boolean flag = false;
public synchronized void set(String name,String sex)
{
if(flag)
try{this.wait();}catch(Exception e){} //如果有东西,就不让再存了,先睡会吧
this.name = name; //没东西不走if直接走这里,把东西存进来。
this.sex = sex;
flag = true; //刚存完要把标记改为true说明里边已经满了。
this.notify(); //已经满了没法存了,唤醒线程池里另一个线程来取。
}
public synchronized void out()
{
if(!flag)
try{this.wait();}catch(Exception e){} //如果没有东西就别取了,先睡会吧
System.out.println(name+"........."+sex); //如果有东西就读这条语句,把东西取出去。
flag = false; //刚取完要把标记改为false说明里边已经空了。
this.notify(); //里边空了没法取了,唤醒另一个进程往里存吧。
}
}
class Input2 implements Runnable
{
private Res r;
Input2(Res r)
{
this.r = r;
}
public void run()
{
int x = 0;
while(true)
{
if(x==0)
r.set("jack","man");
else
r.set("丽丽","女");
x = (x+1)%2;
}
}
}
class Output2 implements Runnable
{
private Res r;
Output2(Res r)
{
this.r = r;
}
public void run()
{
while(true)
{
r.out();
}
}
}
class ImproveCom
{
public static void main(String[] args)
{
Res r = new Res();
new Thread(new Input2(r)).start();
new Thread(new Output2(r)).start();
}
}
jdk1.5以后,synchronized方法被lock方法所替代,wait() notify()方法被Condition对象所封装。
import java.util.concurrent.locks.*;
//jdk1.5以后的改进版生产者消费者
class Resource15
{
private String name;
private int count = 1;
boolean flag = false;
//Lock是一个接口,ReentrantLock是一个实现类,下句是多态。
private Lock lock = new ReentrantLock(); //一个可重入的互斥锁 Lock
//Lock 替代了 synchronized 方法和语句的使用,Condition 替代了 Object 监视器方法的使用。
private Condition condition_pro = lock.newCondition();
private Condition condition_cus = lock.newCondition();
public void set(String name)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(); //释放一定要在finally中
}
}
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 mather implements Runnable
{
private Resource15 res;
mather(Resource15 res)
{
this.res = res;
}
public void run()
{
while(true)
{
try{
res.set("+商品+");
}
catch(InterruptedException e)
{
}
}
}
}
class pater implements Runnable
{
private Resource15 res;
pater (Resource15 res)
{
this.res = res ;
}
public void run()
{
while(true)
{
try{
res.out();
}
catch(InterruptedException e)
{
}
}
}
}
class Test15
{
public static void main(String[] args)
{
Resource15 r = new Resource15();
new Thread(new mather(r)).start();
new Thread(new mather(r)).start();
new Thread(new pater(r)).start();
new Thread(new pater(r)).start();
}
}
停止线程的方法:t1.interrupt(),强制停止一个已经在挂起状态的线程。但是会报出一个错。
守护线程:t1.setDaemon(ture)当你把某些线程标记为守护(后台线程)后,当所有前台线程都结束后所有后台线程自动终结。把建的线程设为守护线程后,主线程没设,则主线程是前台线程,当主线程结束后所有守护线程停止运行。
join方法
调用join 方法的线程具有优先执行权