多线程
死锁
public class DeadLock {
public static void main(String[] args) {
Makeup makeup = new Makeup(0,"莉莉");
Makeup makeup1 = new Makeup(1,"红红");
makeup.start();
makeup1.start();
}
}
class Lipstick{//口红
}
class Mirror{//镜子
}
class Makeup extends Thread{
//需要的资源只有一份,用static保证
static Lipstick l = new Lipstick();
static Mirror m = new Mirror();
int choice;
String girlNmae;
public Makeup(int choice,String girlNmae){
this.choice=choice;
this.girlNmae=girlNmae;
}
@Override
public void run() {
makeUp();
}
private void makeUp(){
//化妆:互相持有对方的锁,即需要拿到对方的资源
if (choice==0){
synchronized (l){//获得口红的锁
System.out.println(this.girlNmae+"获得口红的锁");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//一个对象先将拿到的锁释放再拿别的对象的锁,就不会出现死锁
synchronized (m){//一秒后再获得镜子的锁
System.out.println(this.girlNmae+"获得镜子的锁");
}
}else{
synchronized (m){//获得镜子的锁
System.out.println(this.girlNmae+"获得镜子的锁");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//一个对象先将拿到的锁释放再拿别的对象的锁,就不会出现死锁
}
synchronized (l){//一秒后获得口红的锁
System.out.println(this.girlNmae+"获得口红的锁");
}
}
}
}
Lock
- 更强大的线程同步机制——通过显示定义同步锁随想来实现同步。用Lock对象
- Lock是显式锁(手动开锁和关锁),synchronized是隐式锁,出了作用域自动释放
- Lock是有代码块锁,synchronized有代码块锁和方法锁
- ReentrantLock可重复所,是Lock的子类
火车票问题Lock解决
public class TestLock {
public static void main(String[] args) {
TestLock2 testLock2 = new TestLock2();
new Thread(testLock2,"张三").start();
new Thread(testLock2,"李四").start();
new Thread(testLock2,"王五").start();
}
}
class TestLock2 implements Runnable{
int trictNums = 10;
//定义Lock锁
private final ReentrantLock lock = new ReentrantLock();//点定义一个可重复锁
boolean flag = true;
@Override
public void run() {
while (flag){
try {
lock.lock();//加锁
if (trictNums<=0){
flag=false;
System.out.println("您手慢了");
return;
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"您抢到了第"+trictNums--+"张票");
} finally {
//解锁
lock.unlock();
}
}
}
}
生产者消费者问题
public class TestPC {
public static void main(String[] args) {
WorkShop container = new WorkShop();
new Producer(container).start();
new Consumer(container).start();
}
}
class Producer extends Thread{//生产者
WorkShop container;
public Producer(WorkShop container){
this.container=container;
}
//生产
@Override
public void run() {
for (int i = 1; i < 10; i++) {
container.push(new Chicken(i));
System.out.println("生产了"+i+"只鸡");
}
}
}
class Consumer extends Thread{//消费者
WorkShop container;
public Consumer(WorkShop container){
this.container=container;
}
@Override
public void run() {
for (int i = 1; i < 10; i++) {
System.out.println("消费了"+container.pop().id+"只鸡");
}
}
}
class Chicken{//商品
int id;//产品号
public Chicken(int id) {
this.id = id;
}
}
class WorkShop{//车间
//需要一个容器大小
Chicken[] chickens = new Chicken[10];//定义Chicken类型的数组,所以数组里只能加入Chicken对象
int count = 0;
//生产者放入产品
public synchronized void push(Chicken chicken){
//如果容器满了,就需要等待消费者消费
if (count==chickens.length){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//如果没满,就需要丢入产品
chickens[count]=chicken;//将count索引位置放入商品
count++;
//通知消费者消费
this.notifyAll();
}
//消费者消费产品
public synchronized Chicken pop(){
//判断能否消费
if (count==0) {
//生产者生产,消费者等待
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//可以消费
count--;
Chicken chicken = chickens[count];
//吃完了,通知生产者生产
this.notifyAll();
return chicken;
}
}