目录
线程的创建
方式1
1-1
1.写一个类继承Thread类,重写其run方法
1-2
1.使用匿名内部类,new Thread,重写run方法
方式2
2-1
1.先让一个类实现Runnable接口,并重写run方法
2.创建一个线程对象
3.将任务对象穿进给线程对象
2-2
1.使用匿名内部类
线程的启动
线程名.start();
线程安全问题
原因:
多个线程同时操作同一个数据
解决思路:
保证同一时间只有一个线程操作数据
注意:多个线程持有一个锁对象
任何类的对象都可以是锁对象
解决方案:
方案1:
同步代码块
语法:
synchronized(锁对象){
要同步的代码块
}
方案2:
同步方法
语法:
访问权限修饰符 synchronized 返回值类型 方法名(形参列表){
}
方案3:
同步静态方法
语法:
访问权限修饰符 static synchronized 返回值类型 方法名(形参列表){
}
注意:
同步静态方法的锁对象是该类的类对象,一个类只有一个类对象,在类加载的时候,系统会生成一个对象,类名.class 对象名.getClass();
死锁
原因:
多个线程互相占有对方所需的锁资源
代码
public static void main(String[] args) {
Object lock1 = new Object();
Object lock2 = new Object();
Thread thread01 = new Thread(new Runnable() {
@Override
public void run() {
synchronized (lock1) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (lock2) {
}
}
}
});
Thread thread02 = new Thread(new Runnable() {
@Override
public void run() {
synchronized (lock2) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (lock1) {
}
}
}
});
thread01.start();
thread02.start();
}
}
经验:
不要在同步中使用同步(不绝对)
线程间通讯
作用
多个消息间传递消息
注意
1.线程中的通讯方法都是Object提供的
2.使用当前线程所在的同步代码中的锁对象调用
方法
notify(); 随机唤醒一个由调用该方法的对象作为锁对象的线程
notifyAll(); 唤醒全部由调用该方法的对象作为锁对象的线程
生产者与消费者模式
1.生产者负责生产++
2.消费者进行消费--
3.当数量到达最大值时,生产者进入wait状态
4当库存量等于0时,消费者进入wait状态
5.当生产者开始生产后,唤醒所有的消费者
6.当消费者开始消费后,唤醒所有生产者
创建工厂类,提供生产与消费的方法
创建生产任务类,调用生产的方法
创建消费任务类,调用消费的方法
创建测试类,进行模拟
package com.wangchi.demo04;
public class Factory {
private int num=0;
private final static Integer MAX = 200;
Object lock=new Object();
public synchronized void produce(){
Thread thread = Thread.currentThread();
if (num < MAX) {
num++;
System.out.println(thread.getName()+"制造了一件产品,共有产品"+num+"件");
this.notifyAll();
} else {
System.out.println("仓库存满了");
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public synchronized void sell(){
Thread thread = Thread.currentThread();
if (num > 0) {
num--;
System.out.println(thread.getName()+"卖了一个产品,还剩"+num+"件");
this.notifyAll();
} else {
System.out.println("产品卖完了销售放假");
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
package com.wangchi.demo04;
import java.util.Random;
public class ProduceMan implements Runnable {
private Factory factory;
public ProduceMan(Factory factory) {
this.factory = factory;
}
@Override
public void run() {
while (true) {
factory.produce();
int i = new Random().nextInt(900) + 100;
try {
Thread.sleep(i);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
package com.wangchi.demo04;
import java.util.Random;
public class SellMan implements Runnable{
private Factory factory;
public SellMan(Factory factory) {
this.factory = factory;
}
@Override
public void run() {
while (true){
factory.sell();
int i = new Random().nextInt(500 )+300;
try {
Thread.sleep(i);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
package com.wangchi.demo04;
public class Test01 {
public static void main(String[] args) {
Factory factory=new Factory();
Thread p1=new Thread(new ProduceMan(factory),"老李");
Thread p2=new Thread(new ProduceMan(factory),"老张");
Thread p3=new Thread(new ProduceMan(factory),"老比");
Thread p4=new Thread(new ProduceMan(factory),"老等");
Thread s1=new Thread(new SellMan(factory),"柳岩");
Thread s2=new Thread(new SellMan(factory),"赵丽颖");
Thread s3=new Thread(new SellMan(factory),"迪丽热巴");
Thread s4=new Thread(new SellMan(factory),"古力娜扎");
Thread s5=new Thread(new SellMan(factory),"腾格尔");
p1.start();
p2.start();
p3.start();
p4.start();
s1.start();
s2.start();
s3.start();
s4.start();
s5.start();
}
}