一、synchronized同步方法

论:“线程安全”与“非线程安全”是多线程的经典问题。synchronized()方法就是解决非线程安全的。

1、方法内的变量为线程安全

public void addI(String username) {
try {
int num = 0; \\方法内的变量为线程安全
if (username.equals("a")) {
num = 100;
System.out.println("a set over!");
Thread.sleep(2000);
} else {
num = 200;
System.out.println("b set over!");
}
System.out.println(username + " num=" + num);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

2、实例变量非线程安全

public class HasSelfPrivateNum {
private int num = 0; \\实例变量非线程安全
public void addI(String username) {
try {
if (username.equals("a")) {
num = 100;
System.out.println("a set over!");
Thread.sleep(2000);
} else {
num = 200;
System.out.println("b set over!");
}
System.out.println(username + " num=" + num);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} }

解决方法: 方法前加synchronized关键字。

public class HasSelfPrivateNum {

    private int num = 0;

    synchronized public void addI(String username) {
..............
} }

3、多个对象多个锁

HasSelfPrivateNum.java

public class HasSelfPrivateNum {

    private int num = 0;

    synchronized public void addI(String username) {
try {
if (username.equals("a")) {
num = 100;
System.out.println("a set over!");
Thread.sleep(2000);
} else {
num = 200;
System.out.println("b set over!");
}
System.out.println(username + " num=" + num);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} }

ThreadA

    public class ThreadA extends Thread {

        private HasSelfPrivateNum numRef;

        public ThreadA(HasSelfPrivateNum numRef) {
super();
this.numRef = numRef;
} @Override
public void run() {
super.run();
numRef.addI("a");
} }
ThreadB
public class ThreadB extends Thread {

    private HasSelfPrivateNum numRef;

    public ThreadB(HasSelfPrivateNum numRef) {
super();
this.numRef = numRef;
} @Override
public void run() {
super.run();
numRef.addI("b");
} }

RUN

public class Run {

    public static void main(String[] args) {

        HasSelfPrivateNum numRef1 = new HasSelfPrivateNum();
HasSelfPrivateNum numRef2 = new HasSelfPrivateNum(); ThreadA athread = new ThreadA(numRef1);
athread.start(); ThreadB bthread = new ThreadB(numRef2);
bthread.start(); } }

结果:创建了2个业务实例,产生2个锁,所以运行结果是异步的。同步为synchronized  异步:asynchronized

4、synchronized 锁重入

当一个线程得到一个对象锁时,再次请求该对象锁时是可以再次得到该对象的锁的。继承关系也可重入锁。

当一个线程执行发生异常时,其持有的锁会自动释放。

同步不具有继承性。的在子类方法中添加synchronized的关键字。

public class HasSelfPrivateNum {
synchronized public void service1() {
System.out.println("service1");
service2();
} synchronized public void service2() {
System.out.println("service2");
service3();
} synchronized public void service3() {
System.out.println("service3");
}
}

HasSelfPrivateNum.java

public class mYThread extends Thread {
@Override
public void run() {
HasSelfPrivateNum hspn=new HasSelfPrivateNum();
hspn.service1();
}
public static void main(String[] args) {
mYThread mYThread=new mYThread();
mYThread.start();
}
}

mYThread.java

二、synchronized同步快

synchronized同步方法持有锁后,如果长时间不释放,那另一个线程就必须长时间等待。。这种情况下synchronized同步快来解决

使用方法如图:

1、synchronized同步快之间具有同步性,当线程访问object的一个  synchronized(this)同步代码块时,其他线程对同一个object对象中所有其他的

synchronized(this)同步代码块的访问会被阻塞。

2、synchronized(this)同步代码块是锁定当前对象的。

1、synchronized同步快解决同步方法效率低得弊端

public class Task {

    private String getData1;
private String getData2; public synchronized void doLongTimeTask() {
try {
System.out.println("begin task");
Thread.sleep(3000);
getData1 = "长时间处理任务后从远程返回的值1 threadName="
+ Thread.currentThread().getName();
getData2 = "长时间处理任务后从远程返回的值2 threadName="
+ Thread.currentThread().getName();
System.out.println(getData1);
System.out.println(getData2);
System.out.println("end task");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

Task

public class MyThread1 extends Thread {

    private Task task;

    public MyThread1(Task task) {
super();
this.task = task;
} @Override
public void run() {
super.run();
CommonUtils.beginTime1 = System.currentTimeMillis();
task.doLongTimeTask();
CommonUtils.endTime1 = System.currentTimeMillis();
} }

MyThread1

public class MyThread2 extends Thread {

    private Task task;

    public MyThread2(Task task) {
super();
this.task = task;
} @Override
public void run() {
super.run();
CommonUtils.beginTime2 = System.currentTimeMillis();
task.doLongTimeTask();
CommonUtils.endTime2 = System.currentTimeMillis();
} }

MyThread2

public class CommonUtils {

    public static long beginTime1;
public static long endTime1; public static long beginTime2;
public static long endTime2;
}

CommonUtils

public class Run {

    public static void main(String[] args) {
Task task = new Task(); MyThread1 thread1 = new MyThread1(task);
thread1.start(); MyThread2 thread2 = new MyThread2(task);
thread2.start(); try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
} long beginTime = CommonUtils.beginTime1;
if (CommonUtils.beginTime2 < CommonUtils.beginTime1) {
beginTime = CommonUtils.beginTime2;
} long endTime = CommonUtils.endTime1;
if (CommonUtils.endTime2 > CommonUtils.endTime1) {
endTime = CommonUtils.endTime2;
} System.out.println("耗时:" + ((endTime - beginTime) / 1000));
}
}

Run

修改Task

public class Task {

    private String getData1;
private String getData2; public void doLongTimeTask() {
try {
System.out.println("begin task");
Thread.sleep(3000); String privateGetData1 = "长时间处理任务后从远程返回的值1 threadName="
+ Thread.currentThread().getName();
String privateGetData2 = "长时间处理任务后从远程返回的值2 threadName="
+ Thread.currentThread().getName(); synchronized (this) {
getData1 = privateGetData1;
getData2 = privateGetData2;
} System.out.println(getData1);
System.out.println(getData2);
System.out.println("end task");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

四、java多线程核心技术——synchronized同步方法与synchronized同步快的更多相关文章

  1. Java多线程学习(二)synchronized关键字(2)

    转载请备注地址:https://blog.csdn.net/qq_34337272/article/details/79670775 系列文章传送门: Java多线程学习(一)Java多线程入门 Ja ...

  2. Java多线程学习(二)synchronized关键字(1)

    转载请备注地址: https://blog.csdn.net/qq_34337272/article/details/79655194 Java多线程学习(二)将分为两篇文章介绍synchronize ...

  3. Java多线程核心技术(四)Lock的使用

    本文主要介绍使用Java5中Lock对象也能实现同步的效果,而且在使用上更加方便. 本文着重掌握如下2个知识点: ReentrantLock 类的使用. ReentrantReadWriteLock ...

  4. Java多线程(三):Synchronized

    多线程安全 脏读:多个线程对同一个对象的实例变量进行修改后访问,导致读到的数据是被修改过的. 实例 ThreadDomain16类 public class ThreadDomain16 { priv ...

  5. “全栈2019”Java多线程第十六章:同步synchronized关键字详解

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...

  6. Java多线程核心技术(五)单例模式与多线程

    本文只需要考虑一件事:如何使单例模式遇到多线程是安全的.正确的 1.立即加载 / "饿汉模式" 什么是立即加载?立即加载就是使用类的时候已经将对象创建完毕,常见的实现办法就是直接 ...

  7. 从ConcurrentHashMap的演进看Java多线程核心技术 Java进阶(六)

    本文分析了HashMap的实现原理,以及resize可能引起死循环和Fast-fail等线程不安全行为.同时结合源码从数据结构,寻址方式,同步方式,计算size等角度分析了JDK 1.7和JDK 1. ...

  8. 160711、Java 多线程核心技术梳理

    本文对多线程基础知识进行梳理,主要包括多线程的基本使用,对象及变量的并发访问,线程间通信,lock 的使用,定时器,单例模式,以及线程状态与线程组. java 多线程 基础知识 创建线程的两种方式:1 ...

  9. Java多线程核心技术(六)线程组与线程异常

    本文应注重掌握如下知识点: 线程组的使用 如何切换线程状态 SimpleDataFormat 类与多线程的解决办法 如何处理线程的异常 1.线程的状态 线程对象在不同运行时期有不同的状态,状态信息就处 ...

  10. Java 多线程基础(五)线程同步

    Java 多线程基础(五)线程同步 当我们使用多个线程访问同一资源的时候,且多个线程中对资源有写的操作,就容易出现线程安全问题. 要解决上述多线程并发访问一个资源的安全性问题,Java中提供了同步机制 ...

随机推荐

  1. Apache Shiro (Shiro-550)(cve_2016_4437)远程代码执行 - 漏洞复现

    0x00 漏洞原理 Apache Shiro框架提供了记住密码的功能(RememberMe),用户登录成功后会生成经过加密并编码的cookie.在服务端对rememberMe的cookie值, 先ba ...

  2. Python生成csv中文乱码解决办法

    前言 在Linux下面用python进行数据处理,然后输出为csv格式,如果没有中文一切正常,但是如果有中文,就会出现乱码的问题,本篇将讲述怎么处理这个问题 处理过程 原始代码 #!/usr/bin/ ...

  3. mysql数据库新增、修改、删除字段和修改表名

    Mysql 删除,添加或修改表字段 删除 ALTER TABLE testalter_tbl DROP i; 新增 ALTER TABLE testalter_tbl ADD i INT; 指定位置新 ...

  4. Spring接口

    FactoryBean接口 Spring中有两种类型的Bean:一种是普通的JavaBean:另一种就是工厂Bean(FactoryBean),这两种Bean都受Spring的IoC容器管理. Fac ...

  5. 为什么你写的拦截器注入不了 Java bean?

    一.如何实现拦截器 在Spring Boot项目中,拦截器经常被用来做登陆验证,日志记录等操作.拦截器是Spring提供的,所以可以将拦截器注成bean,由IOC容器来管理.实现拦截器的方式很简单,主 ...

  6. python-网络安全编程第七天(base64模块)

    前言 睡不着,那就起来学习其实base64模块很早之前用过今天做爬虫的时候有个URL需要用它来编码一下 所以百度又学了一下遇到最大的问题就是python3和python2区别问题 python3的这个 ...

  7. "三剑客"之awk心中无剑

    一.awk介绍 awk 是一种程序语言. 它具有一般程序语言常见的功能. 因awk语言具有某些特点, 如 : 使用直译器(Interpreter)不需先行编译; 变量无类型之分(Typeless), ...

  8. 牛客练习赛68 牛牛的无向图 题解(krusal思想)

    题目链接 题目大意 要你查询q 次询问,每次询问给出一个 L ,询问\(\sum_{i=1}^n\sum_{j=i+1}^n[d(i,j)<=L]\).其中 [C] 表示当命题 C 为真的时候为 ...

  9. 牛客练习赛69 火柴排队 题解(dp)

    题目链接 题目大意 给你一个长为n(n<=5e3)的数组a.随机使得k个元素增加d.要你求多大的概率使得,这些数组元素的相对大小不发生改变 输出 n 行每行一个整数,第 i 行的整数表示 k=i ...

  10. JZOJ2020年8月12日提高组反思

    JZOJ2020年8月12日提高组反思 真·难亿一点点 T1 题目长并附带伤害-- 暴力搜 对于字符串,我选择\(Pascal\) T2 概率问题,再见 T3 样例没懂,再见 T4 有史以来见过的条件 ...