java多线程之间通信有两种方式:
- Object提供的wait()和notify() (notifyAll())
- jdk提供的Condition来实现
1、Object提供wait()和notify()
线程通信过程中调用Object的wait()和notify()时,需要获取Object对应的对象锁,因为在调用wait()时需要释放锁
public class MultiThreadComm {
public static void main(String[] args) {
MultiThreadComm comm = new MultiThreadComm();
comm.multiThreadCommunication();
}
public void multiThreadCommunication() {
final Object obj = new Object();
new Thread(new Runnable() {
@Override
public void run() {
synchronized (obj) {
try {
System.out.println("1");
obj.wait();
System.out.println("3");
} catch (InterruptedException e) {
System.out.println("error");
}
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
synchronized (obj) {
System.out.println("2");
obj.notify();
}
}
}).start();
}
}
运行结果
1
2
3
2、jdk提供的Condition
在Condition中的相关方法和Object的方法对应关系:
1、object.wait()和condition.await()
2、object.notify()和condition.signal()
3、object.notifyAll()和condition.signalAll()
public class MultiThreadComm {
public static void main(String[] args) {
MultiThreadComm comm = new MultiThreadComm();
comm.multiThreadCommunication();
}
public void multiThreadCommunication() {
final Lock lock = new ReentrantLock();
final Condition condition = lock.newCondition();
new Thread(new Runnable() {
@Override
public void run() {
try {
lock.lock();
condition.await();
System.out.println("2");
} catch (InterruptedException e) {
System.out.println("error");
} finally {
lock.unlock();
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
lock.lock();
System.out.println("1");
condition.signal();
lock.unlock();
}
}).start();
}
}
运行结果
1
2
3、一道面试题
有三个线程名字分别为A、B和C,打印线程名ABBCCCAAAABBBBBCCCCCC……..直到200个字符为止
package uttp;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
/**
* @Author hzzhangyehui
* @Date 2017/2/16 20:17
*/
public class MultiThread {
public static void main(String[] args) throws Exception {
MultiThread multiThread = new MultiThread();
multiThread.printThreadName();
}
public void printThreadName() throws Exception {
final ReentrantLock lock = new ReentrantLock();
final Condition c1 = lock.newCondition(), c2 = lock.newCondition(), c3 = lock.newCondition();
final AtomicInteger count = new AtomicInteger(1);
final AtomicInteger sum = new AtomicInteger(0);
new Thread(new Runnable() {
@Override
public void run() {
try {
lock.lock();
while (sum.get() <= 200) {
c1.await();
for (int i = 0; i < count.get() && sum.get() < 200; ++i) {
sum.getAndIncrement();
System.out.print(Thread.currentThread().getName());
}
count.getAndIncrement();
c2.signal();
}
} catch (Exception e) {
System.out.println("error");
} finally {
lock.unlock();
}
}
}, "A").start();
new Thread(new Runnable() {
@Override
public void run() {
try {
lock.lock();
while (sum.get() <= 200) {
c2.await();
for (int i = 0; i < count.get() && sum.get() < 200; ++i) {
sum.getAndIncrement();
System.out.print(Thread.currentThread().getName());
}
count.getAndIncrement();
c3.signal();
}
} catch (Exception e) {
System.out.println("error1");
} finally {
lock.unlock();
}
}
}, "B").start();
new Thread(new Runnable() {
@Override
public void run() {
try {
lock.lock();
while (sum.get() <= 200) {
c1.signal();
c3.await();
for (int i = 0; i < count.get() && sum.get() < 200; ++i) {
sum.getAndIncrement();
System.out.print(Thread.currentThread().getName());
}
count.getAndIncrement();
}
} catch (Exception e) {
System.out.println("error2");
} finally {
lock.unlock();
}
}
}, "C").start();
}
}