一、Lock接口
java 1.5以后代替synchronized关键词,更加灵活的,显式的控制锁。
1、
lock.lock()和lock.unlock() 代替 synchronized的作用范围。
2、
condition.await() 代替 object.wait()
condition.signal() 代替 object.notify()
condition.signalAll() 代替 object.notifyAll()
3、同一个锁可以包含多个condition,通过不同的condition,我们控制同一锁对不同条件的加解。
生产者消费者优化:
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class ClassicalThread {
public static void main(String[] args) {
Resourse res = new Resourse();
new Thread(new Producer(res)).start();
new Thread(new Producer(res)).start();
new Thread(new Producer(res)).start();
new Thread(new Resumer(res)).start();
new Thread(new Resumer(res)).start();
new Thread(new Resumer(res)).start();
}
}
class Resourse {
private String name;
private int id = 0;
private boolean flag = true;
private Lock lock = new ReentrantLock();
private Condition produceCondition = lock.newCondition();
private Condition resumeCondition = lock.newCondition();
public void produce(String name) {
lock.lock();
try {
while (!flag) {
try {
produceCondition.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.name = name;
System.out.println("生产" + name + " " + ++id);
flag = false;
resumeCondition.signal();
} finally {
lock.unlock();
}
}
public synchronized void resume() {
lock.lock();
try {
while (flag) {
try {
resumeCondition.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("消费" + name + " " + id);
flag = true;
produceCondition.signal();
} finally {
lock.unlock();
}
}
}
class Producer implements Runnable {
private Resourse res;
public Producer(Resourse res) {
this.res = res;
}
@Override
public void run() {
while (true) {
res.produce("商品");
}
}
}
class Resumer implements Runnable {
private Resourse res;
public Resumer(Resourse res) {
this.res = res;
}
@Override
public void run() {
while (true) {
res.resume();
}
}
}
二、线程的结束
1、控制线程内的循环。
2、特殊情况:当该线程冻结时,会出现主线程结束,但子线程依然冻结,需要interrupt();
interrupt();既不是终结方法,也不是得到锁的唤醒方法。作用是在存在需求时唤醒线程,但此时因为会存在共享变量的问题,因此不会执行代码,而是使睡眠的线程抛出interrupted 异常。通过抛出异常,使该线程跳过共享变量的逻辑,继续运行,结束循环。
即:
try{wait();}catch(interruptedException e){...}
代码实例:
public class StopThread {
public static void main(String[] args) {
Thread t = new Thread(new Runnable() {
boolean flag = true;
int i = 0;
Lock lock = new ReentrantLock();
Condition condition = lock.newCondition();
@Override
public void run() {
lock.lock();
try {
while (flag) {
try {
condition.await();
} catch (InterruptedException e) {
flag = false;
}
System.out.println("第" + i++ + "次");
if (i == 60) {
flag = false;
}
condition.signal();
}
} finally {
lock.unlock();
}
System.out.println("子线程结束");
}
});
t.start();
t.interrupt();
}
}
偷懒偷得自己感觉逻辑都有问题,呵呵哒~