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
的方法sleep
will not release the monitor(LOCK), butwait
will release the monitor(LOCK) and add to the object monitor waiting queue.- use
sleep
not depend on the monitor, butwait
need(synchronized). sleep
not need to be wakeup, butwait
must 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 ...
随机推荐
- smtp常见问题
http://blog.csdn.net/chenfei_5201213/article/details/10138969
- sitecore系统教程之体验编辑器
体验编辑器是一个WYSIWYG编辑器,允许您直接在页面上轻松更改项目.您可以编辑页面上可见的所有项目 - 文本,图形,徽标,链接等. 在体验编辑器中,您可以编辑当前项目的字段以及页面上呈现的任何项目的 ...
- Java多线程-----匿名内部类创建线程
1.继承Thread类创建线程 package com.practise.createthread; public class AnonymousThread { public static v ...
- Game (思维)
#include<bits/stdc++.h> using namespace std; ; char str[maxn][maxn]; int cntx[maxn], cnty[maxn ...
- 20155228 获取技能的成功经验和关于C语言学习的调查
内容提要 你有什么技能比大多人(超过90%以上)更好?针对这个技能的获取你有什么成功的经验?与老师博客中的学习经验有什么共通之处? 有关C语言学习的调查 你是怎么学习C语言的?(作业,实验,教材,其他 ...
- 51ll网产品信息保存为txt文件
import requests from pyquery import PyQuery as pq url='http://www.51xxx.com/Try/index/p/3' headers={ ...
- 输入输出无依赖型函数的GroovySpock单测模板的自动生成工具(上)
目标 在<使用Groovy+Spock轻松写出更简洁的单测> 一文中,讲解了如何使用 Groovy + Spock 写出简洁易懂的单测. 对于相对简单的无外部服务依赖型函数,通常可以使用 ...
- CentOS下shell显示-bash-4.1$不显示用户名路径
Linux CentOS下shell显示-bash-4.1$不显示用户名路径的解决方法. 问题描述: CentOS下新增一个用户,登录进去之后shell脚本的信息如下: -bash-4.1$ \ -b ...
- MyEclipse 10.7(版本:eclipse 3.7.x-Indigo系列)安装activiti-eclipse-plugin插件(流程设计器)
基本信息 1.本机MyEclipse 10.7菜单[Help->About MyEclipse Enterprise Workbench]的版本信息: MyEclipse Enterprise ...
- 海瑞菌的web前端学习直播间
这是本人的web前端学习直播间 一般每天晚上10点--12点为直播时间...以web前端开发为主. 若设备无法打开,请点击链接进入:https://www.huya.com/14958154 setT ...