同步代码块

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区别

  1. sleepThread的方法,而waitobject的方法
  2. sleep will not release the monitor(LOCK), but wait will release the monitor(LOCK) and add to the object monitor waiting queue.
  3. use sleep not depend on the monitor, but wait need(synchronized).
  4. sleep not need to be wakeup, but wait 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 多线程案例的更多相关文章

  1. Java多线程——线程八锁案例分析

    Java多线程——线程八锁案例分析 摘要:本文主要学习了多线程并发中的一些案例. 部分内容来自以下博客: https://blog.csdn.net/dyt443733328/article/deta ...

  2. JAVA多线程之生产者 消费者模式 妈妈做面包案例

    创建四个类 1.面包类 锅里只可以放10个面包 ---装面包的容器2.厨房 kitchen 生产面包 和消费面包  最多生产100个面包3.生产者4消费者5.测试类 多线程经典案例 import ja ...

  3. Java多线程学习笔记

    进程:正在执行中的程序,其实是应用程序在内存中运行的那片空间.(只负责空间分配) 线程:进程中的一个执行单元,负责进程汇总的程序的运行,一个进程当中至少要有一个线程. 多线程:一个进程中时可以有多个线 ...

  4. Java多线程开发系列之四:玩转多线程(线程的控制2)

    在上节的线程控制(详情点击这里)中,我们讲解了线程的等待join().守护线程.本节我们将会把剩下的线程控制内容一并讲完,主要内容有线程的睡眠.让步.优先级.挂起和恢复.停止等. 废话不多说,我们直接 ...

  5. Java多线程同步 synchronized 关键字的使用

    代表这个方法加锁,相当于不管哪一个线程A每次运行到这个方法时,都要检查有没有其它正在用这个方法的线程B(或者C D等),有的话要等正在使用这个方法的线程B(或者C D)运行完这个方法后再运行此线程A, ...

  6. 面试之Java多线程

    Java多线程1.什么是多线程2.为什么需要多线程  有什么优点和缺点3.怎么运行 一.多线程是在软件或硬件上并发执行的技术共享数据空间,内存资源和CPU二.优点:把长时间运行的程序任务放到后台处理, ...

  7. java多线程解决生产者消费者问题

    import java.util.ArrayList; import java.util.List; /** * Created by ccc on 16-4-27. */ public class ...

  8. java多线程系列(三)---等待通知机制

    等待通知机制 前言:本系列将从零开始讲解java多线程相关的技术,内容参考于<java多线程核心技术>与<java并发编程实战>等相关资料,希望站在巨人的肩膀上,再通过我的理解 ...

  9. Java多线程编程核心技术

    Java多线程编程核心技术 这本书有利于对Java多线程API的理解,但不容易从中总结规律. JDK文档 1. Thread类 部分源码: public class Thread implements ...

随机推荐

  1. uvalive 4848 Tour Belt

    题意: 一个KTO被定义为一个特殊的连通块,这个连通块满足一个要求,这个连通块中的最短的边大于 与这个连通相连的不属于这个连通块的边中的最大值. 给出一个图,统计KTO里面的点有多少个.(一个点可以属 ...

  2. 概念、DW介绍

    网页设计知识点大致分为五个部分,分别是: 1.概念.DW介绍: 2.标签: 3.样式表CSS: 4.JQuery: 5.JavaScript 概念.DW介绍: 一.网页的基本结构 <!--文档声 ...

  3. mybatis源码解析6---MappedStatement解析

    MappedStatement类位于mybatis包的org.apache.ibatis.mapping目录下,是一个final类型也就是说实例化之后就不允许改变 MappedStatement对象对 ...

  4. ClassThree__HomeWork

    作业一 使用类的静态字段和构造函数,可以跟踪某个类所创建对象的个数.请写一个类,在任何时候都可以向它查询“你已经创建了多少个对象?”. 代码 public class TestOne {       ...

  5. 微信小程序制作家庭记账本之四

    第四天,仍然对记账本代码进行研究,对按钮的大小设置,颜色,具体位置进行分析,但其中很多代码都不明白.

  6. go语言,golang学习笔记3 用命令下载框架报错问题解决 设置环境变量

    go语言,golang学习笔记3 用命令下载框架报错问题解决 设置环境变量 下载安装:go get github.com/astaxie/beego 首页 - beego: 简约 & 强大并存 ...

  7. php CI框架中URL特殊字符处理与SQL注入隐患

    php CI框架中URL特殊字符处理与SQL注入隐患 php CI框架中URL特殊字符有很多是不支持的,导致像c++,括号这些常用的分类,字符都无法正常显示很头痛,而在配置里增加单引号' 反斜杠\ 这 ...

  8. let的使用 优先于闭包

    let声明的变量在{}中使用,变量的作用域限制在块级域中 举例:使用js动态给ul添加li对象并点击第几项,显示当前点击是第几个 错误代码 window.onload = function(){ va ...

  9. Django框架---- 自定义分页组件

    分页的实现与使用 class Pagination(object): """ 自定义分页 """ def __init__(self,cur ...

  10. 怎样从外网访问内网Tomcat?

    本地安装了一个Tomcat,只能在局域网内访问,怎样从外网也能访问到本地的Tomcat呢?本文将介绍具体的实现步骤. 准备工作 安装并启动Tomcat 默认安装的Tomcat端口是8080. 实现步骤 ...