完成以下功能:两个线程交替输出,如此往复执行50次
读写锁
利用synchronized、wait、notify
必须额外定义一个标记变量
class Business {
boolean flag = true;
public synchronized void subRun() {
while (flag) {
try {
this.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("sub----------------------");
flag = true;
this.notify();
}
public synchronized void mainRun() {
while (!flag) {
try {
this.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("main---------------------");
flag = false;
this.notify();
}
}
利用Lock、Condition
class Business2 {
Lock lock=new ReentrantLock();
Condition condition_m=lock.newCondition();
Condition condition_s=lock.newCondition();
public void subRun() {
try {
lock.lock();
System.out.println("sub----------------------");
condition_m.signal();
condition_s.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
finally {
lock.unlock();
}
}
public void mainRun() {
try {
lock.lock();
//注意先调用另一个condition的signal,再调用本condition的await
//因为调用await后线程会阻塞住(阻塞住后signal执行不到了)并释放锁
condition_s.signal();
condition_m.await();
System.out.println("main---------------------");
} catch (InterruptedException e) {
e.printStackTrace();
}
finally {
lock.unlock();
}
}
}
生产者、消费者
class Business3 {
static Object object=new Object();
List<Integer> list=new ArrayList();
public void consume()
{
while (true)
{
synchronized (object)
{
if(list.size()<=0)
{
try {
System.out.println("消费者进入阻塞状态,目前集合大小为:"+list.size());
object.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
else
{
Integer integer=list.get(0);
list.remove(0);
System.out.println("消费者消费的元素为:"+integer);
object.notifyAll();
}
}
//注意这个sleep的位置放到synchronized的外面,要不然不好演示效果
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void produce()
{
while (true)
{
synchronized (object)
{
if(list.size()>=10)
{
try {
System.out.println("生产者进入阻塞状态,目前集合大小为:"+list.size());
object.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
else
{
Integer integer=new Random().nextInt(1000);
list.add(integer);
System.out.println("生产者生产的元素为:"+integer);
object.notifyAll();
}
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
大概理解了,wait方法会导致本线程进入阻塞状态,并释放本线程持有的锁,notify会唤醒因为调用wait方法进入阻塞状态的线程,但是不会释放锁,所以即使其他线程被唤醒了,如果获取不到锁依然无法执行,必须等到本线程将锁释放后,然后大家一起争夺锁资源
网友评论