等待/通知机制
不使用等待/通知机制实现线程间通信
import java.util.ArrayList;
import java.util.List;
public class MyList {
private List list = new ArrayList();
public void add() {
list.add("gaogagao");
}
public int size() {
return list.size();
}
}
public class Test {
public static void main(String[] args) {
MyList service = new MyList();
ThreadA ta = new ThreadA(service);
ta.setName("A");
ta.start();
ThreadB tb = new ThreadB(service);
tb.setName("B");
tb.start();
}
}
public class ThreadA extends Thread{
private MyList list;
public ThreadA(MyList list) {
super();
this.list = list;
}
public void run() {
try {
for (int i = 0; i < 10; i++) {
list.add();
System.out.println("添加了" + (i + 1) + " 个元素 ");
Thread.sleep(1000);
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public class ThreadB extends Thread{
private MyList list;
public ThreadB(MyList list) {
super();
this.list = list;
}
public void run() {
try {
while (true) {
if (list.size() == 5) {
System.out.println("==5了,线程b要退出了!");
throw new InterruptedException();
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
等待/通知机制的实现
public class Test1 {
public static void main(String[] args) {
try {
String newString = new String("");
newString.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public class Test2 {
public static void main(String[] args) {
try {
String lock = new String();
System.out.println("syn上面");
synchronized (lock) {
System.out.println("syn第一行");
lock.wait();
System.out.println("wait下的代码");
}
System.out.println("syn下面的代码");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class TestAB {
public static void main(String[] args) {
try {
Object lock = new Object();
ThreadA ta = new ThreadA(lock);
ta.start();
Thread.sleep(1000);
ThreadB tb = new ThreadB(lock);
tb.start();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public class ThreadA extends Thread{
private Object lock;
public ThreadA(Object lock) {
super();
this.lock = lock;
}
public void run() {
try {
synchronized (lock) {
System.out.println(" start wait time = " + System.currentTimeMillis());
lock.wait();
System.out.println(" stop wait time = " + System.currentTimeMillis());
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class ThreadB extends Thread{
private Object lock;
public ThreadB(Object lock) {
super();
this.lock = lock;
}
public void run() {
synchronized (lock) {
System.out.println(" start notify time = " + System.currentTimeMillis());
lock.notify();
System.out.println(" stop notify time = " + System.currentTimeMillis());
}
}
}
wait()方法可以使调用该方法的线程释放共享资源的锁,然后从运行状态退出,进入等待队列,直到被再次唤醒;
notify()方法可以随机唤醒等待队列中等待同一共享资源的“一个”线程,并使该线程退出等待队列,进入可运行状态;
notifyAll()方法可以使所有正在等待队列中等待同一共享资源的“全部”线程从等待状态退出,进入可运行状态;
wait()锁释放;notify()锁不释放
public class Service {
public void testMethod(Object lock) {
try {
synchronized (lock) {
System.out.println("begin wait()");
lock.wait();
System.out.println(" end wait()");
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public class TestAB {
public static void main(String[] args) {
Object lock = new Object();
ThreadA ta = new ThreadA(lock);
ta.start();
ThreadB tb = new ThreadB(lock);
tb.start();
}
}
public class ThreadA extends Thread{
private Object lock;
public ThreadA(Object lock) {
super();
this.lock = lock;
}
public void run() {
Service service = new Service();
service.testMethod(lock);
}
}
public class ThreadB extends Thread{
private Object lock;
public ThreadB(Object lock) {
super();
this.lock = lock;
}
public void run() {
Service service = new Service();
service.testMethod(lock);
}
}
当线程呈wait()状态时,调用线程对象的interrupt()方法会出现InterruptedException异常;
方法wait(long)的使用:
带一个参数的wait(long)方法的功能时等待某一段时间内是否有线程对锁进行唤醒,如果超过这个时间则自动唤醒;
其他
通知过早:如果通知过早,则会打乱程序正常的运行逻辑;
等待wait的条件发生彪悍:wait等待的条件发生了变化,也容易造成程序逻辑的混乱;
import java.util.ArrayList;
import java.util.List;
public class ValueObject {
public static List list = new ArrayList();
}
public class Add {
private String lock;
public Add(String lock) {
super();
this.lock = lock;
}
public void add() {
synchronized(lock) {
ValueObject.list.add("anyString");
lock.notifyAll();
}
}
}
public class Subtract {
private String lock;
public Subtract (String lock) {
super();
this.lock = lock;
}
public void subtract() {
try {
synchronized (lock) {
while(ValueObject.list.size() == 0) {
System.out.println(" wait begin ThreadName = "
+ Thread.currentThread().getName());
lock.wait();
System.out.println(" wait end ThreadName = "
+ Thread.currentThread().getName());
}
ValueObject.list.remove(0);
System.out.println("list size = " + ValueObject.list.size());
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class ThreadAdd extends Thread{
private Add p;
public ThreadAdd(Add p) {
super();
this.p = p;
}
public void run() {
p.add();
}
}
public class ThreadSubtract extends Thread{
private Subtract r;
public ThreadSubtract(Subtract r) {
super();
this.r = r;
}
public void run() {
r.subtract();
}
}
import com.highgo.t9_WaitOld.*;
public class Run {
public static void main(String[] args) throws InterruptedException {
String lock = new String("");
Add add = new Add(lock);
Subtract subtract = new Subtract(lock);
ThreadSubtract subtractT1 = new ThreadSubtract(subtract);
subtractT1.setName("subtarctT1");
subtractT1.start();
ThreadSubtract subtractT2 = new ThreadSubtract(subtract);
subtractT2.setName("subtarctT2");
subtractT2.start();
Thread.sleep(1000);
ThreadAdd addThread = new ThreadAdd(add);
addThread.setName("addThread");
addThread.start();
}
}
生产者/消费者模式的实现:
一生产与一消费:
多生产与多消费:
操作值,操作栈,假死问题
//消费者
public class C {
private String lock;
public C(String lock) {
super();
this.lock = lock;
}
public void getValue() {
try {
synchronized(lock) {
while(ValueObject.value.equals("")) {
System.out.println("消费者"
+ Thread.currentThread().getName() + "* WAITING了");
lock.wait();
}
System.out.println("消费者"
+ Thread.currentThread().getName() + " RUNNABLE了");
System.out.println("get的值是 " + ValueObject.value);
ValueObject.value = "";
lock.notifyAll();
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
//生产者
public class P {
private String lock;
public P(String lock) {
super();
this.lock = lock;
}
public void setValue() {
try {
synchronized (lock) {
while(!ValueObject.value.equals("")) {
System.out.println("生产者"
+ Thread.currentThread().getName() + " WAITING了 * * *");
lock.wait();
}
System.out.println("生产者"
+ Thread.currentThread().getName() + " RUNNABLE了 ");
String value = System.currentTimeMillis() + "_" + System.nanoTime();
System.out.println("set的值是 " + value);
ValueObject.value = value;
lock.notifyAll();
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public class ThreadP extends Thread{
private P p;
public ThreadP(P p) {
super();
this.p = p;
}
public void run() {
while(true) {
p.setValue();
}
}
}
public class ThreadC extends Thread{
private C r;
public ThreadC(C r) {
super();
this.r = r;
}
public void run() {
while(true) {
r.getValue();
}
}
}
public class ValueObject {
public static String value = "";
}
//解决假死的方法,将P.java 和 C.java 文件中的notify()改为notifyAll(),
//它的原理就是不光通知同类线程也包括异类线程;
public class Run {
public static void main(String[] args) throws InterruptedException {
String lock = new String("");
P p = new P(lock);
C r = new C(lock);
ThreadP[] pThread = new ThreadP[2];
ThreadC[] rThread = new ThreadC[2];
for (int i = 0; i < 2; i++) {
pThread[i] = new ThreadP(p);
pThread[i].setName("生产者" + (i + 1));
rThread[i] = new ThreadC(r);
rThread[i].setName("消费者" + (i + 1));
pThread[i].start();
rThread[i].start();
}
Thread.sleep(5000);
Thread[] threadArray =
new Thread[Thread.currentThread().getThreadGroup().activeCount()];
Thread.currentThread().getThreadGroup().enumerate(threadArray);
for (int i = 0; i < threadArray.length; i++) {
System.out.println(threadArray[i].getName() + " " + threadArray[i].getState());
}
}
}
通过管道进行线程间通信:字节流/字符流
import java.io.IOException;
import java.io.PipedOutputStream;
public class WriteData {
public void writeMethod(PipedOutputStream out) {
try {
System.out.println("write : ");
for(int i = 0; i < 300; i++) {
String outData = "" + (i + 1);
out.write(outData.getBytes());
System.out.print(outData);
}
System.out.println();
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
import java.io.IOException;
import java.io.PipedInputStream;
public class ReadData {
public void readMethod(PipedInputStream input) {
try {
System.out.println("read : ");
byte[] byteArray = new byte[20];
int readLength = input.read(byteArray);
while(readLength != -1) {
String newData = new String(byteArray, 0, readLength);
System.out.print(newData);
readLength = input.read(byteArray);
}
System.out.println();
input.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
import java.io.PipedInputStream;
public class ThreadR extends Thread{
private ReadData read;
private PipedInputStream input;
public ThreadR(ReadData read, PipedInputStream input) {
super();
this.read = read;
this.input = input;
}
public void run() {
read.readMethod(input);
}
}
import java.io.PipedOutputStream;
public class ThreadW extends Thread{
private WriteData write;
private PipedOutputStream out;
public ThreadW(WriteData write, PipedOutputStream out) {
super();
this.write = write;
this.out = out;
}
public void run() {
write.writeMethod(out);
}
}
import java.io.IOException;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
public class Run {
public static void main(String[] args) {
try {
WriteData writeData = new WriteData();
ReadData readData = new ReadData();
PipedInputStream inputStream = new PipedInputStream();
PipedOutputStream outputStream = new PipedOutputStream();
outputStream.connect(inputStream);
ThreadR threadR= new ThreadR(readData, inputStream);
threadR.start();
Thread.sleep(2000);
ThreadW threadW= new ThreadW(writeData, outputStream);
threadW.start();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
等待/通知之交叉备份:
public class BackupA extends Thread{
private DBTools dbtools;
public BackupA(DBTools dbtools) {
super();
this.dbtools = dbtools;
}
public void run() {
dbtools.backupA();
}
}
public class BackupB extends Thread{
private DBTools dbtools;
public BackupB(DBTools dbtools) {
super();
this.dbtools = dbtools;
}
public void run() {
dbtools.backupB();
}
}
public class DBTools {
volatile private boolean prevIsA = false;
synchronized public void backupA() {
try {
while(prevIsA == true) {
wait();
}
for (int i = 0; i < 5; i++ ) {
System.out.println("*****");
}
prevIsA = true;
notifyAll();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
synchronized public void backupB() {
try {
while(prevIsA == false) {
wait();
}
for (int i = 0; i < 5; i++ ) {
System.out.println("+++++");
}
prevIsA = false;
notifyAll();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class Run {
public static void main(String[] args) {
DBTools dbtools = new DBTools();
for (int i = 0; i < 10; i++) {
BackupB output = new BackupB(dbtools);
output.start();
BackupA input = new BackupA(dbtools);
input.start();
}
}
}