Java线程笔记
1. 线程的介绍:
Java中每一个对象都可以作为锁,这是synchronized实现同步的基础;
- 普通同步方法(实例方法),锁是当前实例对象 ,进入同步代码前要获得当前实例的锁;
- 静态同步方法,锁是当前类的class对象 ,进入同步代码前要获得当前类对象的锁;
- 同步方法块,锁是括号里面的对象,对给定对象加锁,进入同步代码库前要获得给定对象的锁;
2. synchronized 关键字;
关键字synchronized可以保证在同一时刻,只有一个线程可以执行某个方法或某个代码块;用于解决多线程共同操作共享数据的问题。
3. 方法介绍;
- wait() :当前线程进入等待状态,释放锁,停止执行wait() 方法后面的语句;
- notify() :
- notifyAll() : 通知所有等待相同资源的线程,不会立即释放锁,当前线程执行完后释放锁,即,notifyAll()通知发出后,需当前线程执行完后释放锁,其他等待的线程才能抢到资源;
4. 生产者-消费者实现方式一 (synchronized、wait和notify)
4.1 先定义一个资源池,用于存放线程共享资源,并提供生产、消费资源的方法
1 //定义一个资源池的类Resource
2
3 class Resource {
4 private int num = 0;
5 private int size = 10;
6
7 // 从资源池中取资源
8 public synchronized void remove() {
9 if (num > 0) {
10 num--;
11 System.out.println("消费者" + Thread.currentThread().getName() + "消耗一件资源," + "当前线程池有" + num + "个");
12 //当前同步语句块执行完前不释放锁,继续执行完后释放锁,所以通知唤醒等待的线程后,其他线程不能立即执行;
13 notifyAll();
14 } else {
15 try {
16 System.out.println("消费者" + Thread.currentThread().getName() + "线程进入开始[进入]等待状态");
17 //wait释放锁,停止继续执行直到被唤醒才继续往下执行
18 //如果没有资源,则消费者进入等待状态
19 wait();
20 System.out.println("消费者" + Thread.currentThread().getName() + "线程[结束]等待状态");
21 } catch (InterruptedException e) {
22 // TODO Auto-generated catch block
23 e.printStackTrace();
24 }
25 }
26 }
27
28 // 往资源池中添加资源
29 public synchronized void add() {
30 if (num < size) {
31 num++;
32 System.out.println(Thread.currentThread().getName() + "生产一件资源,当前资源池有" + num + "个");
33 // 通知所有正在等待队列中等待同一共享资源的 “全部线程” 退出等待队列,进入可运行状态
34 //notify不释放锁,必须执行完notify()方法所在的synchronized代码块后才释放
35 notifyAll();
36 try {
37 Thread.sleep(5000);
38 } catch (InterruptedException e) {
39 // TODO Auto-generated catch block
40 e.printStackTrace();
41 }
42 } else {
43 try {
44 wait();// 当前线程的生产者进入等待状态,并释放锁
45 System.out.println(Thread.currentThread().getName() + "线程进入等待");
46 } catch (InterruptedException e) {
47 // TODO Auto-generated catch block
48 e.printStackTrace();
49 }
50
51 }
52 }
53 }
4.2 定义生产者
//定义生产者线程
/*
* 生产者线程
*/
class ProducerThread extends Thread {
private Resource resource;
public ProducerThread(Resource resource) {
super();
this.resource = resource;
}
public void run() {
// 不断地生产资源
while (true) {
try {
Thread.sleep(8000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
resource.add();
}
}
}
4.3 定义消费者
//定义消费者线程
/*
* 消费者线程
*/
class ConsumerThread extends Thread {
private Resource resource;
public ConsumerThread(Resource resource) {
super();
this.resource = resource;
}
public void run() {
while (true) {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
resource.remove();
}
}
}
4.4 定义测试主类
1 public class ProducerConsumerWithWaitNofity {
2
3 public static void main(String[] args) {
4 // TODO Auto-generated method stub
5 Resource resource = new Resource();
6 //生产者线程
7 ProducerThread p1 = new ProducerThread(resource);
8 // ProducerThread p2 = new ProducerThread(resource);
9 // ProducerThread p3 = new ProducerThread(resource);
10
11 //消费者线程
12 ConsumerThread c1 = new ConsumerThread(resource);
13 ConsumerThread c2 = new ConsumerThread(resource);
14
15 p1.start();
16 // p2.start();
17 // p3.start();
18 c1.start();
19 c2.start();
20 }
21
22 }
备注:代码案例转载自:https://www.cnblogs.com/xiaowenboke/p/10469125.html