Java多线程编程核心技术
链接:https://pan.baidu.com/s/1waW7B9PTmkNMS-qkh6LNKg 提取码:cm4i
注意:多线程情况下,只有持有相同的锁,才能达到同步效果
原理都是基于wait和notify来实现的
public class ValueObject {
public static String value = "";
}
生产者
public class P {
private String lock;
public P(String lock){
this.lock = lock;
}
public void setValue(){
try {
synchronized (lock){
if (!ValueObject.value.equals("")){
lock.wait();
}
String value = System.currentTimeMillis() + "_" + System.nanoTime();
ValueObject.value = value;
System.out.println("set的值是:" + value);
lock.notify();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
消费者
public class C {
private String lock;
public C(String lock){
this.lock = lock;
}
public void getValue(){
try {
synchronized (lock){
if (ValueObject.value.equals("")){
lock.wait();
}
String value = ValueObject.value;
System.out.println("get的值是:" + value);
ValueObject.value = "";
lock.notify();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class Run {
// 单个生产者消费者
public static void main(String[] args) {
String lock = "";
P p = new P(lock);
C c = new C(lock);
ThreadP threadP = new ThreadP(p);
ThreadC threadC = new ThreadC(c);
threadP.start();
threadC.start();
}
}
class ThreadC extends Thread{
private C c;
public ThreadC(C c){
this.c = c;
}
@Override
public void run() {
while (true){
c.getValue();
}
}
}
class ThreadP extends Thread{
private P p;
public ThreadP(P p){
this.p = p;
}
@Override
public void run() {
while (true){
p.setValue();
}
}
}
生产者
public class P {
private String lock;
public P(String lock){
this.lock = lock;
}
public void setValue(){
try {
synchronized (lock){
while (!ValueObject.value.equals("")){
lock.wait();
}
String value = System.currentTimeMillis() + "_" + System.nanoTime();
ValueObject.value = value;
System.out.println("生产者:"+ Thread.currentThread().getName() + value);
lock.notifyAll();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
消费者
public class C {
private String lock;
public C(String lock){
this.lock = lock;
}
public void getValue(){
try {
synchronized (lock){
while (ValueObject.value.equals("")){
lock.wait();
}
String value = ValueObject.value;
System.out.println("消费者:"+ Thread.currentThread().getName() + value);
ValueObject.value = "";
lock.notifyAll();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class Run {
public static void main(String[] args) throws InterruptedException {
String lock = "";
P p = new P(lock);
C c = new C(lock);
ThreadP[] threadP = new ThreadP[2];
ThreadC[] threadC = new ThreadC[2];
for (int i = 0; i < 2; i++) {
threadP[i] = new ThreadP(p);
threadP[i].setName("生产者" + (i+1));
threadC[i] = new ThreadC(c);
threadC[i].setName("消费者" + (i+1));
threadP[i].start();
threadC[i].start();
}
}
}
class ThreadC extends Thread{
private C c;
public ThreadC(C c){
this.c = c;
}
@Override
public void run() {
while (true){
c.getValue();
}
}
}
class ThreadP extends Thread{
private P p;
public ThreadP(P p){
this.p = p;
}
@Override
public void run() {
while (true){
p.setValue();
}
}
}
上述代码若使用notify唤醒单个线程,可能会造成“ 假死 ”(notify唤醒同类线程造成假死),所以使用notifyAll唤醒所有线程
public class MyStack {
private List list = new ArrayList();
synchronized public void push() {
try {
while (list.size() == 1) {
this.wait();
}
list.add("anything: " + Math.random());
this.notifyAll();
System.out.println("push=" + list.size());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
synchronized public void pop() {
try {
while (list.size() == 0) {
this.wait();
}
System.out.println(list.get(0));
list.remove(0);
this.notifyAll();
System.out.println("pop=" + list.size());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
生产者
public class Provider {
private MyStack stack;
public Provider(MyStack stack){
this.stack = stack;
}
public void pushService(){
stack.push();
}
}
消费者
public class Consumer {
private MyStack stack;
public Consumer(MyStack stack){
this.stack = stack;
}
public void popService(){
stack.pop();
}
}
public class Run {
public static void main(String[] args) {
MyStack stack = new MyStack();
Provider provider = new Provider(stack);
Consumer consumer = new Consumer(stack);
Provider provider1 = new Provider(stack);
CThread cThread = new CThread(consumer);
PThread pThread = new PThread(provider);
PThread pThread1 = new PThread(provider1);
cThread.start();
pThread.start();
pThread1.start();
}
}
class CThread extends Thread{
private Consumer consumer;
public CThread(Consumer consumer) {
this.consumer = consumer;
}
@Override
public void run(){
while (true) {
consumer.popService();
}
}
}
class PThread extends Thread{
private Provider provider;
public PThread(Provider provider){
this.provider = provider;
}
@Override
public void run() {
while (true) {
provider.pushService();
}
}
}
lock.lock();
lock.unlock(); // 一般写在finally当中,因为出现异常锁不会自动释放
public class Service {
private Lock lock = new ReentrantLock();
private Condition condition = lock.newCondition();
public void await(){
try {
lock.lock();
System.out.println("await时间为:" + System.currentTimeMillis());
condition.await();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void signal(){
try {
lock.lock();
System.out.println("signal时间为:" + System.currentTimeMillis());
condition.signal();
} finally {
lock.unlock();
}
}
}
public class Service {
private ReentrantLock lock = new ReentrantLock();
private Condition condition = lock.newCondition();
private boolean hasValue = false;
public void set(){
try {
lock.lock();
while (hasValue == true){
condition.await();
}
System.out.println("######");
hasValue = true;
condition.signalAll();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void get(){
try {
lock.lock();
while (hasValue == false){
condition.await();
}
System.out.println("*****");
hasValue = false;
condition.signalAll();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
线程类
public class Run {
public static void main(String[] args) {
Service service = new Service();
ThreadA[] a = new ThreadA[2];
ThreadB[] b = new ThreadB[2];
for (int i = 0; i < 2; i++) {
a[i] = new ThreadA(service);
b[i] = new ThreadB(service);
a[i].start();
b[i].start();
}
}
}
class ThreadA extends Thread {
private Service service;
public ThreadA(Service service) {
this.service = service;
}
@Override
public void run() {
super.run();
while (true) {
service.set();
}
}
}
class ThreadB extends Thread {
private Service service;
public ThreadB(Service service) {
this.service = service;
}
@Override
public void run() {
super.run();
while (true) {
service.get();
}
}
}
// 设置公平锁与非公平锁
boolean isFair = true;
ReentrantLock lock = new ReentrantLock(isFair);
public class Run {
volatile private static int nextPrintWho = 1;
private static ReentrantLock lock = new ReentrantLock();
private static Condition conditionA = lock.newCondition();
private static Condition conditionB = lock.newCondition();
private static Condition conditionC = lock.newCondition();
public static void main(String[] args) {
Thread threadA = new Thread(){
@Override
public void run() {
try {
lock.lock();
while (nextPrintWho != 1){
conditionA.await();
}
nextPrintWho = 2;
for (int i = 0; i < 3; i++) {
System.out.println("ThreadA:" + (i + 1));
}
conditionB.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
};
Thread threadB = new Thread(){
@Override
public void run() {
try {
lock.lock();
while (nextPrintWho != 2){
conditionB.await();
}
nextPrintWho = 3;
for (int i = 0; i < 3; i++) {
System.out.println("ThreadB:" + (i + 1));
}
conditionC.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
};
Thread threadC = new Thread(){
@Override
public void run() {
try {
lock.lock();
while (nextPrintWho != 3){
conditionC.await();
}
nextPrintWho = 1;
for (int i = 0; i < 3; i++) {
System.out.println("ThreadC:" + (i + 1));
}
conditionA.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
};
Thread[] ta = new Thread[5];
Thread[] tb = new Thread[5];
Thread[] tc = new Thread[5];
for (int i = 0; i < 5; i++) {
ta[i] = new Thread(threadA);
tb[i] = new Thread(threadB);
tc[i] = new Thread(threadC);
ta[i].start();
tb[i].start();
tc[i].start();
}
}
}
ReentrantLock具有完全互斥排他效果,好处是通过同步保证了线程安全,缺点则是效率低下。因此,JDK推出了ReentrantReadWriteLock类,在某些不需要操作实例变量方法中,可以使用ReentrantReadWriteLock来提高效率。
读写锁ReentrantReadWriteLock具有以下特点:
可以通过下面的代码去自行测试:
public class Service {
private static ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();
public static void main(String[] args) {
Service service = new Service();
ThreadA ta = new ThreadA(service);
ta.setName("A");
ta.start();
ThreadB tb = new ThreadB(service);
tb.setName("B");
tb.start();
}
synchronized public static void set() {
try {
readWriteLock.writeLock().lock();
System.out.println("这是写锁" + Thread.currentThread().getName() +
System.currentTimeMillis());
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
readWriteLock.writeLock().unlock();
}
}
public void get() {
try {
readWriteLock.readLock().lock();
System.out.println("这是读锁" + Thread.currentThread().getName() +
System.currentTimeMillis());
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
readWriteLock.readLock().unlock();
}
}
}
class ThreadA extends Thread {
private Service service;
public ThreadA(Service service) {
this.service = service;
}
@Override
public void run() {
service.set();
}
}
class ThreadB extends Thread {
private Service service;
public ThreadB(Service service) {
this.service = service;
}
@Override
public void run() {
service.set();
}
}
我认为本书主要讲了Synchronize和Lock的使用,等待通知机制的各种实现,还有一些零碎的线程方法,本文并没有进行罗列。本书还讲解了上述线程操作的基本姿势,但并没有特别的深入原理,不过这本书的配套书Java并发编程则是对这本书原理的详细讲解,也算是进阶。