-----------android培训、java培训、java学习型技术博客、期待与您交流!------------
线程间的通信
线程间的通信,其实就是多个线程在操作同一个资源,但是操作的动作不同,需要有相互的配合。
在这些方法在操作同步中线程时,都必须要标识它们所操作线程持有的锁,只有同一个锁上的被等待线程,可以被同一个锁上notify唤醒。不可以对不同锁中的线程进行唤醒。等待和唤醒必须是同一个锁。
package thread;
class Resource {
private String name;
private int count = 1;
private boolean flag = false;
public synchronized void set(String n) throws Exception {
while(flag) {
this.wait();
}
this.name = n + count;
count++;
System.out.println("生产者" + name);
flag = true;
this.notifyAll();
}
public synchronized void get() throws Exception {
while(!flag) {
this.wait();
}
System.out.println("消费者" + "........." + name);
flag = false;
this.notifyAll();
}
}
class Productor implements Runnable {
private Resource s;
Productor(Resource s) {
this.s = s;
}
@Override
public void run() {
while (true) {
try {
s.set("烤鸭");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
class Consumer implements Runnable {
private Resource s;
Consumer(Resource s) {
this.s = s;
}
@Override
public void run() {
while (true) {
try {
s.get();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
public class ThreadDemo2 {
public static void main(String[] args) {
Resource s = new Resource();
Thread t0 = new Thread(new Productor(s));
Thread t1 = new Thread(new Consumer(s));
Thread t2= new Thread(new Productor(s));
Thread t3 = new Thread(new Consumer(s));
t0.start();
t1.start();
t2.start();
t3.start();
}
}
JDK1.5 中提供了多线程升级解决方案。
将同步Synchronized替换成现实Lock操作。
将Object中的wait,notify notifyAll,替换了Condition对象。
该对象可以Lock锁 进行获取。
该示例中,实现了本方只唤醒对方操作。
Lock:替代了Synchronized
lock
unlock
newCondition()
Condition:替代了Object wait notify notifyAll
await();
signal();
signalAll();
package thread;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Pro_Con {
static BoundedBuffer bf = new BoundedBuffer();
public static void main(String[] args) {
new Thread(new Runnable() {
@Override
public void run() {
try {
while(true){
String[] str={"a","b","c","d","e","f","g"};
for (int i = 0; i < str.length; i++) {
bf.put(str[i]);
}
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
try {
int count=0;
while(true){
System.out.print(bf.take()+"\t");
count++;
if(count%4==0){
System.out.println();
}
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
}
}
class BoundedBuffer {
final Lock lock = new ReentrantLock();
final Condition notFull = lock.newCondition();
final Condition notEmpty = lock.newCondition();
final Object[] items = new Object[3];
int putptr, takeptr, count;
public void put(Object x) throws InterruptedException {
lock.lock();
try {
while (count == items.length)
notFull.await();
items[putptr] = x;
if (++putptr == items.length)
putptr = 0;
++count;
notEmpty.signal();
} finally {
lock.unlock();
}
}
public Object take() throws InterruptedException {
lock.lock();
try {
while (count == 0)
notEmpty.await();
Object x = items[takeptr];
if (++takeptr == items.length)
takeptr = 0;
--count;
notFull.signal();
return x;
} finally {
lock.unlock();
}
}
}