java synchronized
一、简介
常用的有如下几种方式
synchronized(this)、synchronized(Object)与synchronized修饰静态方法、synchronized(class)
二、修饰本身对象
如下两种写法是具有一样的效果,都是锁住自己本身的对象,当同一对象多次调用时,同步锁会起作用。
1.synchronized代码块
写法一:
public synchronized void method()
{
// todo
}
写法二:
public void method()
{
synchronized(this) {
// todo
}
}
2.非synchronized代码块
class Counter implements Runnable{
private int count;
public Counter() {
count = 0;
}
public void countAdd() {
synchronized(this) {
for (int i = 0; i 5; i ++) {
try {
System.out.println(Thread.currentThread().getName() + ":" + (count++));
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
//非synchronized代码块,未对count进行读写操作,所以可以不用synchronized
public void printCount() {
for (int i = 0; i 5; i ++) {
try {
System.out.println(Thread.currentThread().getName() + " count:" + count);
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void run() {
String threadName = Thread.currentThread().getName();
if (threadName.equals("A")) {
countAdd();
} else if (threadName.equals("B")) {
printCount();
}
}
}
调用代码
Counter counter = new Counter();
Thread thread1 = new Thread(counter, "A");
Thread thread2 = new Thread(counter, "B");
thread1.start();
thread2.start();
结果
A:0
B count:1
A:1
B count:2
A:2
B count:3
A:3
B count:4
A:4
B count:5
上面代码中countAdd是一个synchronized的,printCount是非synchronized的。从上面的结果中可以看出一个线程访问一个对象的synchronized代码块时,别的线程可以访问该对象的非synchronized代码块而不受阻塞。
三、同步一段代码
当没有明确的对象作为锁,只是想让一段代码同步时,可以创建一个特殊的对象来充当锁:
class Test implements Runnable
{
private byte[] lock = new byte[0]; // 特殊的instance变量
public void method()
{
synchronized(lock) {
// todo 同步代码块
}
}
public void run() {
}
}
四、修饰类
如果synchronized作用的对象是一个静态方法或一个类,则它取得的锁是对类,该类所有的对象同一把锁,那也就是说对任何对象都是同步的。
1.修饰类
class ClassName {
public void method() {
synchronized(ClassName.class) {
// todo
}
}
}
2.修饰静态方法
class SyncThread implements Runnable {
public synchronized static void method() {
//todo
}
}
参考:https://blog.csdn.net/luoweifu/article/details/46613015
java synchronized 相关文章
基于C语言的java串口通信程序
目录 1.前言 2.windows ? 串口通信API 3.C/C++封装 ? 动态运行库 4.JAVA-JNI ? java程序调用C++程序 一、前言 ensp?;写这个博客主要是因为自己想用java写一个小小的后端服务器,其中要处理由51单片机传送来的一些数据。单片机的数据由USB转串口发送至上位机
java-字符流
前言 昨天学习了java的字节流,可以用字节流来读写文件。但是读取和写入的内容并不是内容本身,而是其对应的ASCII码。今天学习的字符流就可以规避这个问题,将内容以字符的形式进行读写。 使用字符流读取文件 1 package IO流; 2 3 import java.io.FileReader
Java进阶专题(二十五) 分布式锁原理与实现
前言 ?现如今很多系统都会基于分布式或微服务思想完成对系统的架构设计。那么在这一个系统中,就会存在若干个微服务,而且服务间也会产生相互通信调用。那么既然产生了服务调用,就必然会存在服务调用延迟或失败的问题。当出现这种问题,服务端会进行重试等
Java 经验书
目录 目录 目录 正文 字节 转 String Base64Encoder 的使用 正文 字节 转 String 在开发中,会遇到各种 byte 类型转换为 String 的情况 下面做些记录 // 1. String.valueOf() 效率最高的方法String s = String.valueOf('c'); String s = String.valueOf(new c
Java常用的函数式接口
Supplier T 接口 java.util.function.Supplier T 接口仅包含一个无参的方法: T get() :用来获取一个泛型参数指定类型的对象数据。 Supplier T 接口被称之为生产型接口,指定接口的泛型是什么类型,那么接口中的 get方法就会产生什么类型的数据。 示例 pack
实验-继承super.doc
Account.java package com.atguigu.exer2;public class Account { private int id;//账号 private double balance;//余额 private double annualInterestRate;//年利率 public Account(int id, double balance, double annualInterestRate) { super(); this.
一篇文章图文并茂地带你轻松学完 JavaScript 闭包
JavaScript 闭包 为了更好地理解 JavaScript 闭包,笔者将先从 JavaScript 执行上下文以及 JavaScript 作用域开始写起,如果读者对这方面已经了解了,可以直接跳过。 1. 执行上下文 简单来说, JavaScript 有三种代码运行环境,分别是: Global Code 是 JavaS
Java基础(10) | 抽象
#什么是抽象方法 加上abstract关键字,然后去掉方法体,直接分号结束 抽象方法所在的类必须是抽象类才行,在class之前写上abstract即可 public abstract class Animal{ //抽象类 public abstract void eat(); //抽象方法} # 注意事项 抽象方法所在的类必须是
专业Java报表工具Stimulsoft Reports.Java常见问题解答(二)
Stimulsoft Reports.Java是一个专为在Java应用程序中的报表进行交互和处理的报表工具。 Java技术允许在不同的平台、不同的操作系统和不同的硬件上使用程序。正因为这样,Stimulsoft Reports.Java现在几乎在任何地方都可用,同时还是一个拥有高质量的功能和用
Unit5Java数据类型
Unit5Java数据类型 一、Java标识如何命名 标识符就是名字,包括变量名,类名,方法名 Java标识符命名规则:由数字,字母,$组成,不能以数字开头,不能是关键字 二、Java关键字 abstract continue for new switch assert default goto package synchronized