Java 多线程案例
同步代码块
SynchronizedTest类,用来表示取票功能
package concurency.chapter6;
public class SynchronizedTest implements Runnable {
public static final int MAX = 250;
private int index = 0;
@Override
public void run() {
while(true) {
if(ticket())
break;
}
}
// synchronized 此时锁的是 this 锁的是一个对象,别弄错了
private synchronized boolean ticket() {
if(index >= MAX)
return true;
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " " + (++index));
return false;
}
}
Ticket 模拟游乐园放票
package concurency.chapter6;
public class Ticket {
public static void main(String[] args) {
final SynchronizedTest synRunnable = new SynchronizedTest();
Thread t1 = new Thread(synRunnable, "窗口1");
Thread t2 = new Thread(synRunnable, "窗口2");
Thread t3 = new Thread(synRunnable, "窗口3");
t1.start(); t2.start(); t3.start();
}
}
synchronized 同步方法时,其实是同步的this对象
下面可以证明
package concurency.chapter6;
public class SynchronizedThis {
public static void main(String[] args) {
LockThis l1 = new LockThis();
new Thread("thread1"){
@Override
public void run() {
l1.m1();
}
}.start();
new Thread("thread2"){
@Override
public void run() {
l1.m2();
}
}.start();
}
}
class LockThis {
public synchronized void m1() {
try {
System.out.println(Thread.currentThread().getName() + " method1");
Thread.sleep(3_000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public synchronized void m2() {
try {
System.out.println(Thread.currentThread().getName() + " method2");
Thread.sleep(3_000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
synchronized 同步静态方法时,其实是同步的class
package concurency.chapter6;
public class SynchronizedThis {
public static void main(String[] args) {
new Thread("thread1"){
@Override
public void run() {
LockThis.m1();
}
}.start();
new Thread("thread2"){
@Override
public void run() {
LockThis.m2();
}
}.start();
}
}
class LockThis {
public static synchronized void m1() {
try {
System.out.println(Thread.currentThread().getName() + " method1");
Thread.sleep(3_000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static synchronized void m2() {
try {
System.out.println(Thread.currentThread().getName() + " method2");
Thread.sleep(3_000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
死锁小案例
Service1 两个方法. m1和m2
package concurency.chapter7;
public class Service1 {
private final Object lock1 = new Object();
public Service2 service2;
public Service1(Service2 service2) {
this.service2 = service2;
}
public void m1() {
synchronized(lock1) {
System.out.println("---m1---");
service2.s1();
}
}
public void m2() {
synchronized(lock1) {
System.out.println("---m2---");
}
}
}
Service2 两个方法, s1和s2
package concurency.chapter7;
public class Service2 {
public void s1() {
synchronized (lock2) {
System.out.println("---s1---");
}
}
public void s2() {
synchronized (lock2) {
System.out.println("---s2---");
service1.m2();
}
}
private final Object lock2 = new Object();
public Service1 service1;
void setService1(Service1 service1) {
this.service1 = service1;
}
}
死锁尝试
package concurency.chapter7;
public class DeadLockTest {
public static void main(String[] args) {
Service2 service2 = new Service2();
Service1 service1 = new Service1(service2);
service2.setService1(service1);
new Thread() {
@Override
public void run() {
while(true)
service2.s2();
}
}.start();
new Thread() {
@Override
public void run() {
while(true)
service1.m1();
}
}.start();
}
}
jstack命令查看线程
Found one Java-level deadlock:
=============================
"Thread-1":
waiting to lock monitor 0x0000000017ceddd8 (object 0x00000000d5f7e150, a java.lang.Object),
which is held by "Thread-0"
"Thread-0":
waiting to lock monitor 0x0000000017cec938 (object 0x00000000d5f806c8, a java.lang.Object),
which is held by "Thread-1"
Java stack information for the threads listed above:
===================================================
"Thread-1":
at concurency.chapter7.Service2.s1(Service2.java:6)
- waiting to lock <0x00000000d5f7e150> (a java.lang.Object)
at concurency.chapter7.Service1.m1(Service1.java:16)
- locked <0x00000000d5f806c8> (a java.lang.Object)
at concurency.chapter7.DeadLockTest$2.run(DeadLockTest.java:21)
"Thread-0":
at concurency.chapter7.Service1.m2(Service1.java:21)
- waiting to lock <0x00000000d5f806c8> (a java.lang.Object)
at concurency.chapter7.Service2.s2(Service2.java:13)
- locked <0x00000000d5f7e150> (a java.lang.Object)
at concurency.chapter7.DeadLockTest$1.run(DeadLockTest.java:13)
Found 1 deadlock.
生产者与消费者
单个生产者 单个消费者
package concurency.chapter8;
public class ConsumerAndProducer {
int index = 0;
private final Object LOCK = new Object();
volatile boolean isProduce = false;
private void produce() {
synchronized(LOCK) {
if( isProduce ) {
try {
LOCK.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
// 没生产过
index++;
System.out.println("product->" + index);
isProduce = true;
LOCK.notify();
}
}
}
private void consume() {
synchronized (LOCK) {
if(isProduce) {
System.out.println("consume->" + index);
isProduce = false;
LOCK.notify();
} else {
try {
LOCK.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
ConsumerAndProducer cp = new ConsumerAndProducer();
new Thread("producer") {
@Override
public void run() {
while(true)
cp.produce();
}
}.start();
new Thread("consumer") {
@Override
public void run() {
while (true)
cp.consume();
}
}.start();
}
}
多个生产者 多个消费者
package concurency.chapter8;
import java.util.stream.Stream;
public class ConsumerAndProducerV2 {
int index = 0;
private final Object LOCK = new Object();
volatile boolean isProduce = false;
private void produce() {
synchronized (LOCK) {
while(isProduce) {
try {
LOCK.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
index++;
System.out.println(Thread.currentThread().getName() + " " + index);
isProduce = true;
LOCK.notifyAll();
}
}
private void consume() {
synchronized (LOCK) {
while(!isProduce) {
try {
LOCK.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName() + " " + index);
isProduce = false;
LOCK.notifyAll();
}
}
public static void main(String[] args) {
ConsumerAndProducerV2 cp = new ConsumerAndProducerV2();
Stream.of("Producer1", "Producer2", "Producer3").forEach((name)->{
new Thread(name) {
@Override
public void run() {
while (true) {
cp.produce();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
});
Stream.of("Consumer1", "Consumer2", "Consumer3", "Consumer4").forEach((name)->{
new Thread(name) {
@Override
public void run() {
while(true) {
cp.consume();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
});
}
}
wait和sleep区别
sleep是Thread的方法,而wait是object的方法sleepwill not release the monitor(LOCK), butwaitwill release the monitor(LOCK) and add to the object monitor waiting queue.- use
sleepnot depend on the monitor, butwaitneed(synchronized). sleepnot need to be wakeup, butwaitmust need to notify.
数据采集多线程案例
package concurency.chapter8;
import java.util.*;
/**
* @author draymonder
* @Date 2019/02/14
*/
public class DataCapture {
private static final Object LOCK = new Object();
private static final int MAX = 5;
private static LinkedList<Controller> list = new LinkedList<>();
public static void main(String[] args) {
ArrayList<Thread> threads = new ArrayList<>();
// 开辟10个线程, 每个线程采集数据
Arrays.asList("Mac1", "Mac2", "Mac3", "Mac4", "Mac5", "Mac6", "Mac7", "Mac8", "Mac9", "Mac10").stream()
.map(DataCapture::createDataCaptureThread).forEach(dataCaptureThread->{
dataCaptureThread.start();
// 放入threads List中
threads.add(dataCaptureThread);
});
// main线程等这10个线程 执行完再结束
threads.forEach((thread)->{
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
Optional.of("the data capture have finished").ifPresent(System.out::println);
}
private static Thread createDataCaptureThread(String name) {
return new Thread(()->{
Optional.of(Thread.currentThread().getName() + " is begin").ifPresent(System.out::println);
// 如果大于等于5个线程,后面的线程就等待
synchronized (LOCK) {
while(list.size() >= MAX) {
try {
LOCK.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
list.add(new Controller());
}
Optional.of(Thread.currentThread().getName() + " is running").ifPresent(System.out::println);
try {
Thread.sleep(10_000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 执行完毕
synchronized (LOCK) {
Optional.of(Thread.currentThread().getName() + " end").ifPresent(System.out::println);
// 执行完 删除一个
list.removeFirst();
LOCK.notifyAll();
}
},name);
}
static class Controller{}
}
执行结果
Mac1 is begin
Mac1 is running
Mac2 is begin
Mac2 is running
Mac3 is begin
Mac3 is running
Mac4 is begin
Mac4 is running
Mac5 is begin
Mac5 is running
Mac6 is begin
Mac7 is begin
Mac8 is begin
Mac9 is begin
Mac10 is begin
Mac1 end
Mac10 is running
Mac2 end
Mac6 is running
Mac3 end
Mac9 is running
Mac4 end
Mac7 is running
Mac5 end
Mac8 is running
Mac10 end
Mac9 end
Mac7 end
Mac6 end
Mac8 end
the data capture have finished
Java 多线程案例的更多相关文章
- Java多线程——线程八锁案例分析
Java多线程——线程八锁案例分析 摘要:本文主要学习了多线程并发中的一些案例. 部分内容来自以下博客: https://blog.csdn.net/dyt443733328/article/deta ...
- JAVA多线程之生产者 消费者模式 妈妈做面包案例
创建四个类 1.面包类 锅里只可以放10个面包 ---装面包的容器2.厨房 kitchen 生产面包 和消费面包 最多生产100个面包3.生产者4消费者5.测试类 多线程经典案例 import ja ...
- Java多线程学习笔记
进程:正在执行中的程序,其实是应用程序在内存中运行的那片空间.(只负责空间分配) 线程:进程中的一个执行单元,负责进程汇总的程序的运行,一个进程当中至少要有一个线程. 多线程:一个进程中时可以有多个线 ...
- Java多线程开发系列之四:玩转多线程(线程的控制2)
在上节的线程控制(详情点击这里)中,我们讲解了线程的等待join().守护线程.本节我们将会把剩下的线程控制内容一并讲完,主要内容有线程的睡眠.让步.优先级.挂起和恢复.停止等. 废话不多说,我们直接 ...
- Java多线程同步 synchronized 关键字的使用
代表这个方法加锁,相当于不管哪一个线程A每次运行到这个方法时,都要检查有没有其它正在用这个方法的线程B(或者C D等),有的话要等正在使用这个方法的线程B(或者C D)运行完这个方法后再运行此线程A, ...
- 面试之Java多线程
Java多线程1.什么是多线程2.为什么需要多线程 有什么优点和缺点3.怎么运行 一.多线程是在软件或硬件上并发执行的技术共享数据空间,内存资源和CPU二.优点:把长时间运行的程序任务放到后台处理, ...
- java多线程解决生产者消费者问题
import java.util.ArrayList; import java.util.List; /** * Created by ccc on 16-4-27. */ public class ...
- java多线程系列(三)---等待通知机制
等待通知机制 前言:本系列将从零开始讲解java多线程相关的技术,内容参考于<java多线程核心技术>与<java并发编程实战>等相关资料,希望站在巨人的肩膀上,再通过我的理解 ...
- Java多线程编程核心技术
Java多线程编程核心技术 这本书有利于对Java多线程API的理解,但不容易从中总结规律. JDK文档 1. Thread类 部分源码: public class Thread implements ...
随机推荐
- Rpgmakermv(18)GALV RollCredits
原文: Galv's Roll Credits ---------------------------------------------------------------------------- ...
- html5-css背景
div{ width: 300px; height: 300px; border:50px groove rgba(200,60,30,0.5); /*background-c ...
- jQuery选择器--selector1,selector2,selectorN和ancestor descendant
selector1,selector2,selectorN 概述 将每一个选择器匹配到的元素合并后一起返回.你可以指定任意多个选择器,并将匹配到的元素合并到一个结果内 参数 selector1 ...
- Java Redis JNI
基本参考菜鸟教程,java下载直接安装,注意文件名和类名需要一致的问题: redis下载以后按菜鸟教程linux下安装,方式编译运行ok: Java使用redis按菜鸟教程下载.jar,保存在本地某个 ...
- canvas绘图,html5 k线图,股票行情图
canvas绘图,html5 k线图,股票行情图 canvas跟其他标签一样,也可以通过css来定义样式.但这里需要注意的是:canvas的默认宽高为300px * 150px,在css中为canva ...
- usdt钱包开发,比特币协议 Omni 层协议 USDT
usdt钱包开发 比特币协议 -> Omni 层协议 -> USDT USDT是基于比特币omni协议的一种代币: https://omniexplorer.info/asset/31 I ...
- TensorFlow入门,基本介绍,基本概念,计算图,pip安装,helloworld示例,实现简单的神经网络
TensorFlow入门,基本介绍,基本概念,计算图,pip安装,helloworld示例,实现简单的神经网络
- vue:vuex详解
一.什么是Vuex? https://vuex.vuejs.org/zh-cn 官方说法:Vuex 是一个专为 Vue.js应用程序开发的状态管理模式.它采用集中式存储管理应用的所有组件的状态,并以相 ...
- python-数据分析与展示(Numpy、matplotlib、pandas)---1
笔记内容整理自mooc上北京理工大学嵩天老师python系列课程数据分析与展示,本人小白一枚,如有不对,多加指正 1.ndarray对象的属性 .ndim..shape..size(元素个数,不是占用 ...
- 使用WebClient下载网页,用正则匹配需要的内容
WebClient是一个操作网页的类 webClient web=new WebClient(): web.DownloadString(网页的路径,可以是本地路径);--采用的本机默认的编码格式 ...