Java多线程的例子及synchronized关键字锁定对象的用法

简介:

该例子所应用场景:一个线程负责生产,多个线程(该例为3个)负责消费;生产者不断的往堆栈中加入数据,消费者不断的从堆栈中取数据。

代码如下:

package com.xs.mail.thread;

import java.util.ArrayList;
import java.util.List;

class Widget {
}

class WidgetMaker extends Thread {
	List<Widget> finishedWidgets = new ArrayList<Widget>();

	public void run() {
		try {
			while (true) {
				//每1秒钟生产一个Widget
				Thread.sleep(1000);// act busy
				Widget w1 = new Widget();
				// 也就是说需要5秒钟才能新产生一个Widget,这决定了一定要用notify而不是notifyAll
				// 因为上面两行代码不是同步的,如果用notifyAll则所有线程都企图冲出wait状态
				// 第一个线程得到了锁,并取走了Widget(这个过程的时间小于5秒,新的Widget还没有生成)
				// 并且解开了锁,然后第二个线程获得锁(因为用了notifyAll其他线程不再等待notify语句
				// ,而是等待finishedWidgets上的锁,一旦锁放开了,他们就会竞争运行),运行
				// finishedWidgets.remove(0),但是由于finishedWidgets现在还是空的,
				// 于是产生异常
				// ***********这就是为什么下面的那一句不能用notifyAll而是要用notify

				synchronized (finishedWidgets) {
					finishedWidgets.add(w1);
					finishedWidgets.notify(); // 这里只能是notify而不能是notifyAll
				}
			}
		} catch (InterruptedException e) {
		}
	}

	public Widget waitForWidget() {
		synchronized (finishedWidgets) {
			if (finishedWidgets.size() == 0) {
				try {
					System.out.println("暂停线程:" + Thread.currentThread().getName());
					finishedWidgets.wait();
				} catch (InterruptedException e) {
				}
			}
			return finishedWidgets.remove(0);
		}
	}
}

public class WidgetUser extends Thread {
	private WidgetMaker maker;

	public WidgetUser(String name, WidgetMaker maker) {
		super(name);
		this.maker = maker;
	}

	public void run() {
		while (true) {
			Widget w = maker.waitForWidget();
			System.out.println(getName() + " got a widget");
		}
	}

	public static void main(String[] args) {
		WidgetMaker maker = new WidgetMaker();
		maker.start();
		new WidgetUser("Tom", maker).start();
		new WidgetUser("Jack", maker).start();
		new WidgetUser("Marry", maker).start();
	}
}


目录
相关文章
|
3天前
|
缓存 Java 开发者
Java多线程编程的陷阱与最佳实践####
本文深入探讨了Java多线程编程中常见的陷阱,如竞态条件、死锁和内存一致性错误,并提供了实用的避免策略。通过分析典型错误案例,本文旨在帮助开发者更好地理解和掌握多线程环境下的编程技巧,从而提升并发程序的稳定性和性能。 ####
|
3天前
|
安全 Java 开发者
Java中的多线程编程:从基础到实践
本文深入探讨了Java多线程编程的核心概念和实践技巧,旨在帮助读者理解多线程的工作原理,掌握线程的创建、管理和同步机制。通过具体示例和最佳实践,本文展示了如何在Java应用中有效地利用多线程技术,提高程序性能和响应速度。
24 1
|
11天前
|
安全 Java 开发者
Java 多线程并发控制:深入理解与实战应用
《Java多线程并发控制:深入理解与实战应用》一书详细解析了Java多线程编程的核心概念、并发控制技术及其实战技巧,适合Java开发者深入学习和实践参考。
|
10天前
|
存储 安全 Java
Java多线程编程中的并发容器:深入解析与实战应用####
在本文中,我们将探讨Java多线程编程中的一个核心话题——并发容器。不同于传统单一线程环境下的数据结构,并发容器专为多线程场景设计,确保数据访问的线程安全性和高效性。我们将从基础概念出发,逐步深入到`java.util.concurrent`包下的核心并发容器实现,如`ConcurrentHashMap`、`CopyOnWriteArrayList`以及`BlockingQueue`等,通过实例代码演示其使用方法,并分析它们背后的设计原理与适用场景。无论你是Java并发编程的初学者还是希望深化理解的开发者,本文都将为你提供有价值的见解与实践指导。 --- ####
|
4月前
|
存储 监控 Java
Java多线程优化:提高线程池性能的技巧与实践
Java多线程优化:提高线程池性能的技巧与实践
123 1
|
7月前
|
设计模式 监控 Java
Java多线程基础-11:工厂模式及代码案例之线程池(一)
本文介绍了Java并发框架中的线程池工具,特别是`java.util.concurrent`包中的`Executors`和`ThreadPoolExecutor`类。线程池通过预先创建并管理一组线程,可以提高多线程任务的效率和响应速度,减少线程创建和销毁的开销。
223 2
|
7月前
|
Java 数据库
【Java多线程】对线程池的理解并模拟实现线程池
【Java多线程】对线程池的理解并模拟实现线程池
61 1
|
4月前
|
安全 算法 Java
17 Java多线程(线程创建+线程状态+线程安全+死锁+线程池+Lock接口+线程安全集合)(下)
17 Java多线程(线程创建+线程状态+线程安全+死锁+线程池+Lock接口+线程安全集合)
81 6
|
4月前
|
存储 安全 Java
17 Java多线程(线程创建+线程状态+线程安全+死锁+线程池+Lock接口+线程安全集合)(中)
17 Java多线程(线程创建+线程状态+线程安全+死锁+线程池+Lock接口+线程安全集合)
89 5
|
4月前
|
存储 安全 Java
17 Java多线程(线程创建+线程状态+线程安全+死锁+线程池+Lock接口+线程安全集合)(上)
17 Java多线程(线程创建+线程状态+线程安全+死锁+线程池+Lock接口+线程安全集合)
87 3