在Java面试的情况中,大多数情况下,线程间的通信机制指的是线程间的交互,即线程的唤醒和阻塞。并不是字面意义上的多个线程之间互相共享和交换数据的“通信”。
优点:
由于多线程共享地址空间和数据空间,所以多个线程间的通信是一个线程的数据可以直接提供给其他线程使用,而不必通过操作系统(也就是内核的调度)。 进程间的通信则不同,它的数据空间的独立性决定了它的通信相对比较复杂,需要通过操作系统。
几种方式:
Object.wait 与 Object.notifytifyAll
LockSupport.park 与 LockSupport.unpark
ReentrantLock + Condition
共享内存方式:volatile 关键字、辅助类(CountDownLatch、CyclicBarrier、Semaphore)
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 = new ReentrantLock();
private Condition cond_pro = lock.newCondition();
private Condition cond_con = lock.newCondition();
public void set(String name) throws InterruptedException//生产方法
{
lock.lock();
try
{
while (flag)
cond_pro.await();
this.name = name+"____"+count++;
System.out.println(Thread.currentThread().getName()+"_______"+"生产者"+this.name);
flag = true;
cond_con.signal();
}
finally //
{
lock.unlock();
}
}
public void out()throws InterruptedException
{
lock.lock();
try
{
while (!flag)
cond_con.await();
System.out.println(Thread.currentThread().getName()+"______"+"消费者"+this.name);
flag = false;
cond_pro.signal();
}
finally
{
lock.unlock();
}
}
}
class Consumer implements Runnable
{
private Resource res;
public Consumer(Resource res)
{
this.res = res;
}
public void run()
{
while (true)
{
try
{
res.out();
}
catch (InterruptedException e)
{
}
}
}
}
class Producer implements Runnable
{
private Resource res;
public Producer(Resource res)
{
this.res = res;
}
public void run()
{
while (true)
{
try
{
res.set("+商品+");
}
catch (InterruptedException e)
}
}
}
}