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 ...
随机推荐
- Yii2开发小技巧
工作中或多或少会用到的关于 Yii2 的小技巧的一个总结,包括model.controller.view或者配置文件的一些写法. 模型相关 获取查询SQL $query = User::find()- ...
- hdu1762 树的上的查询
2015-10-07 20:44:42 题意问的是给了一颗树,然后又1000000次查询u,v,问不在树路径上的点的编号最小值,以1为根 建这颗树,然后在同一棵子树中的点子让就输出1 否则我们记录每个 ...
- AELF(ELF)区块链项目介绍
AELF(ELF)区块链项目介绍,Aelf在交易所上的名称是ELF,最近涨了不少了,可以长期关注逢低建仓,根据自身情况可以适当轻仓配置点.AELF总结下来就是希望打造一个B2B的区块链开放式OS系统. ...
- idea下导入Tomcat源码
对于web开发者来说,如果明白了tomcat那对于开发还是后面的学习都是有很大益处的,但在网上看了很多的文章,总是没弄好,经历了很久才弄好了,写个文章记录下,希望也能帮助到其他人.下载Tomcat源码 ...
- CRM 权限设置
表结构的设计 权限表 url -url地址的正则表达式 ^$ title - 标题 角色表 name - 角色名称 permissions 多对多关联权限表 (权限和角色的关系表) 用户表 name ...
- build docker deivcemapper
1.创建一个虚拟快设备 dd if=/dev/zero of=4G.img bs=1M count=4096 2.创建loop device 可以先用losetup -f 查看空闲的loop设备 lo ...
- JavaUtil smtp 邮件发送
需要用到的jar包:javax.mail.jar package com.lee.util; import java.io.UnsupportedEncodingException; import j ...
- pycharm快捷键及常用设置
Alt+Enter 自动添加包 shift+O 自动建议代码补全 Ctrl+t SVN更新 Ctrl+k SVN提交 Ctrl + / 注释(取消注释)选择的行 Ctrl+Shift+F 高级查找 C ...
- 在MyEclipse中使用javadocAPI文档
开始啦 1.打开MyEclipse,选中要导出的项目,右击Exprot弹出窗口,选择java----javadoc点击next到下一界面. 2.选出要导出的项目或要添加的项目,在browse中选择路径 ...
- qt中QtreeWidget与QstackWidget关联的问题
过程:要做一个图书管理系统,主界面是类似于这样的 左边是类似于树形空间的东西,当点击左边的左边的窗体的时候,右边的窗口也会跟着切换. 为了实现这个功能,必须要有两个控件,QTreeWidget和Qst ...