JAVA多线程(3)——如何加锁
1、加锁不正确导致数据不一致:m1执行过程中,m2(未加synchronized)可以执行,因为m2不用获得锁就可以执行
1 public class TT implements Runnable {
2 int b = 100;
3
4 public synchronized void m1() throws Exception {
5 b = 1000;
6 System.out.println("in m1() before sleep,b="+b);
7 Thread.sleep(5000);
8 System.out.println("in m1() after sleep,b="+b);
9 }
10
11 public void m2() {
12 //public synchronized void m2() throws Exception {
13 b = 199;
14 System.out.println("in m2(),b="+b);
15 }
16
17 public void run() {
18 try {
19 m1();
20 } catch (Exception e) {
21 e.printStackTrace();
22 }
23 }
24
25 public static void main(String[] args) throws Exception {
26 TT tt = new TT();
27 System.out.println("in main() just after new TT(),b=" + tt.b);
28 Thread t = new Thread(tt);
29 t.start();
30
31 Thread.sleep(1000); //为了让m1能够执行b=1000的赋值
32 tt.m2(); // 主线程执行m2
33
34 System.out.println("in main() last,b=" + tt.b);
35 }
36 }
结果:
D:\聚划算\技术部\编程练习\TestThread\Sync>java TT
in main() just after new TT(),b=100
in m1() before sleep,b=1000
in m2(),b=199
in main() last,b=199
in m1() after sleep,b=199 //main线程先于t线程结束吗?
说明:锁定当前对象 只是针对synchronized 这段话,另外的线程完全有可能访问没有锁定的方法(即不带synchronized 的方法)
问题:要保证对资源b的正确访问,需要考虑所有访问b的所有方法,是否需要加同步:加了同步效率可能变低、不加同步可能会出现数据不一致
问题:main线程先于t线程结束吗?
解答:会,main方法即使执行完最后的语句,JVM也不会结束该程序,要等到主线程中的所有其它线程都结束之后,才结束该JAVA应用程序
2、解决上述访问资源b,数据不一致的问题:把所有访问b的方法加锁,m1执行过程,m2一定执行不了,执行m2时必须要得到当前对象的锁才能执行
1 public class TT implements Runnable {
2 int b = 100;
3
4 public synchronized void m1() throws Exception {
5 b = 1000;
6 System.out.println("in m1() before sleep,b="+b);
7 Thread.sleep(5000);
8 System.out.println("in m1() after sleep,b="+b);
9 }
10
11 public synchronized void m2() {
12 //public synchronized void m2() throws Exception {
13 b = 199;
14 System.out.println("in m2(),b="+b);
15 }
16
17 public void run() {
18 try {
19 m1();
20 } catch (Exception e) {
21 e.printStackTrace();
22 }
23 }
24
25 public static void main(String[] args) throws Exception {
26 TT tt = new TT();
27 System.out.println("in main() just after new TT(),b=" + tt.b);
28 Thread t = new Thread(tt);
29 t.start();
30
31 Thread.sleep(1000); //为了让m1能够执行b=1000的赋值
32 tt.m2();
33
34 System.out.println("in main() last,b=" + tt.b);
35 }
36 }
结果:
D:\聚划算\技术部\编程练习\TestThread\Sync>java TT
in main() just after new TT(),b=100
in m1() before sleep,b=1000
in m1() after sleep,b=1000 //m1执行完了才会执行m2
in m2(),b=199
in main() last,b=199
举例:
JAVA多线程(3)——如何加锁的更多相关文章
- java多线程(五)-访问共享资源以及加锁机制(synchronized,lock,voliate)
对于单线程的顺序编程而言,每次只做一件事情,其享有的资源不会产生什么冲突,但是对于多线程编程,这就是一个重要问题了,比如打印机的打印工作,如果两个线程都同时进行打印工作,那这就会产生混乱了.再比如说, ...
- Java 多线程加锁的方式总结及对比(转载)
转自https://blog.csdn.net/u010842515/article/details/67634813 参考博文:http://www.cnblogs.com/handsomeye/p ...
- java多线程加锁是对谁加锁?
1.java多线程加锁是对谁加锁? 答:当然是对共享资源加锁啊,对谁进行访问修改,就对象进行加锁.以便使多线程按序访问此共享对象 比如: 在具体的Java代码中需要完成一下两个操作:把竞争访问的资源类 ...
- 40个Java多线程问题总结
前言 Java多线程分类中写了21篇多线程的文章,21篇文章的内容很多,个人认为,学习,内容越多.越杂的知识,越需要进行深刻的总结,这样才能记忆深刻,将知识变成自己的.这篇文章主要是对多线程的问题进行 ...
- Java多线程基础知识篇
这篇是Java多线程基本用法的一个总结. 本篇文章会从一下几个方面来说明Java多线程的基本用法: 如何使用多线程 如何得到多线程的一些信息 如何停止线程 如何暂停线程 线程的一些其他用法 所有的代码 ...
- 第一章 Java多线程技能
1.初步了解"进程"."线程"."多线程" 说到多线程,大多都会联系到"进程"和"线程".那么这两者 ...
- java从基础知识(十)java多线程(下)
首先介绍可见性.原子性.有序性.重排序这几个概念 原子性:即一个操作或多个操作要么全部执行并且执行的过程不会被任何因素打断,要么都不执行. 可见性:一个线程对共享变量值的修改,能够及时地被其它线程看到 ...
- Java多线程-并发容器
Java多线程-并发容器 在Java1.5之后,通过几个并发容器类来改进同步容器类,同步容器类是通过将容器的状态串行访问,从而实现它们的线程安全的,这样做会消弱了并发性,当多个线程并发的竞争容器锁的时 ...
- Java多线程编程核心技术---学习分享
继承Thread类实现多线程 public class MyThread extends Thread { @Override public void run() { super.run(); Sys ...
- Java多线程总结之线程安全队列Queue
在Java多线程应用中,队列的使用率很高,多数生产消费模型的首选数据结构就是队列.Java提供的线程安全的Queue可以分为阻塞队列和非阻塞队列,其中阻塞队列的典型例子是BlockingQueue,非 ...
随机推荐
- Spring Cloud 之OpenFeign
Spring Cloud 之OpenFeign 一:简介 Feign是一个声明式(对比RestTemplate编程式)的服务客户端,即通过@FeignClient注解即可声明一个接口(interf ...
- JNI c++ 与 java 通信过程
JNI(Java Native Interface)是Java提供的一种机制,用于在Java和本地C/C++代码之间进行通信.下面是JNI C++与Java通信的一般过程: 1. 编写Java代码:首 ...
- NOIP模拟测试A3
A. 谜之阶乘 题目是让我们把 \(n\) 分解成两个阶乘的商,本来想推个式子什么的,结果发现推不出来. 我们知道,阶乘的增长速率非常的快啊!那么这个 \(b - a\) 的值肯定不会太大,我们可以暴 ...
- Spring 的依赖注入
Spring 的依赖注入 @ 目录 Spring 的依赖注入 每博一文案 1. 依赖注入 1.1 构造注入 1.1.1 通过参数名进行构造注入 1.1.2 通过参数的下标,进行构造注入 1.1.3 不 ...
- Linux0.11内核笔记(-)
基础知识 C语言.汇编知识.嵌入式汇编.x86处理器和编程的相关知识和.UNIX操作系统设计 Linus在最初开发Linux操作系统时参考了MINIX操作系统:<操作系统:设计与实现>一种 ...
- python-多继承构造函数声明问题
背景 有场景分别定义两组逻辑,随后有统一入口做基类属性的整合 其中两组逻辑的积累构造函数定义入参不同 设计类继承图如: 实际的使用方式抽象为[使用] 小节 实际开发过程中遇到问题 先说结论 pytho ...
- 6、Mybatis之高级查询
6.1.创建接口.映射文件和测试类 ++++++++++++++++++++++++++分割线++++++++++++++++++++++++++ 注意namespace属性值为对应接口的全限定类名 ...
- Java将MySQL建表语句转换为SQLite的建表语句
Java将MySQL建表语句转换为SQLite的建表语句 源代码: package com.fxsen.platform.core.util; import java.util.HashMap; im ...
- MAUI+Blazor混合应用开发示例
前言 笔者之前在公司搭建过一套生产管理系统,该系统要求能和硬件进行串口通信,同时又要提供后台信息查询.笔者给出的解决方案就是:MAUI + Blazor,这样只需要提供一套UI,就能满足桌面端.移动端 ...
- 快手Java一面11问(附参考答案)
现在已经到了面试招聘比较火热的时候,后续会分享一些面试真题供大家复习参考.准备面试的过程中,一定要多看面经,多自测! 今天分享的是一位贵州大学的同学分享的快手一面面经. 快手一面主要会问一些基础问题, ...