synchronized:意思是 同步,也就是 共享资源

Synchronized修饰方法:对象锁

Static Synchronized修饰方法:类锁

下面代码手动敲一遍,就会理解

 一、Synchronized修饰方法

1、一个对象,启动多个线程,竞争一把对象锁

package sync;
/*
* 一个对象,启动多个线程,竞争一把对象锁
*/
public class MyThread extends Thread{ private int count = 5; public synchronized void run() {
count--;
System.out.println(this.currentThread().getName() + " count = " + count);
} public static void main(String[] args) {
//新建一个对象
MyThread myThread = new MyThread();
//启动多个线程
Thread t1 = new Thread(myThread,"t1");
Thread t2 = new Thread(myThread,"t2");
Thread t3 = new Thread(myThread,"t3");
Thread t4 = new Thread(myThread,"t4");
Thread t5 = new Thread(myThread,"t5");
t1.start();
t2.start();
t3.start();
t4.start();
t5.start();
}
}

输出结果:

t1 count = 4
t4 count = 3
t5 count = 2
t3 count = 1
t2 count = 0

这五个线程,哪个先执行,哪个后执行,要看CPU调度

2、多个对象,启动多个线程,竞争多把对象锁

package sync;

public class MultiThread {

	private int num = 0;

	public synchronized void printNum(String tag) {
try {
if(tag.equals("a")) {
num = 100;
System.out.println("tag a , set num over!");
Thread.sleep(1000);
System.out.println("tag " + tag + ", num = " + num);
}else {
num = 200;
System.out.println("tag b , set num over!");
Thread.sleep(1000);
System.out.println("tag " + tag + ", num = " + num);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
} public static void main(String[] args) {
//新建两个对象m1 、m2
MultiThread m1 = new MultiThread();
MultiThread m2 = new MultiThread(); //新建第一个线程,调用m1对象的printNum()方法
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
m1.printNum("a");
} });
//新建第二个线程,调用m2对象的printNum()方法
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
m2.printNum("b");
}
});
//同时启动两个线程
t1.start();
t2.start(); //是先执行完线程t1,再执行线程t2吗?
}
}

输出结果:

tag b , set num over!
tag a , set num over!
tag b, num = 200
tag a, num = 100

  

可以看到,线程t1和线程t2是同时执行,两个线程互不影响,独立执行,因此输出结果自然不分先后.

第一个对象m1访问后,锁住m1这个对象;然后,第二个对象m2继续访问,不会被m1锁影响到。

结论:

(1)synchronized是对象锁,多个对象多个锁,锁的是对象。

(2)而不是把一个方法或者一个类当作锁(一个Class类可以new多个对象嘛)

二、Static Synchronized修饰方法

在静态方法上加上synchronized关键字,表示锁定class类,类一级别的锁(独占class类)

无论new多少个对象去访问该静态synchronized方法,都要排队一个个访问,竞争同一把锁(class这个锁)

package sync;

public class MultiThread {

	private static int num = 0;

	public static synchronized void printNum(String tag) {
try {
if(tag.equals("a")) {
num = 100;
System.out.println("tag a , set num over!");
Thread.sleep(1000);
System.out.println("tag " + tag + ", num = " + num);
}else {
num = 200;
System.out.println("tag b , set num over!");
Thread.sleep(1000);
System.out.println("tag " + tag + ", num = " + num);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
} public static void main(String[] args) {
//新建两个对象m1 、m2
MultiThread m1 = new MultiThread();
MultiThread m2 = new MultiThread(); //新建第一个线程,调用m1对象的printNum()方法
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
m1.printNum("a");
} });
//新建第二个线程,调用m2对象的printNum()方法
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
m2.printNum("b");
}
});
//同时启动两个线程
t1.start();
t2.start(); //是先执行完线程t1,再执行线程t2吗?
}
}

  

输出结果:

tag b , set num over!
tag b, num = 200
tag a , set num over!
tag a, num = 100

  

可以看到:

先执行完一个线程b,再执行下一个线程a

结论:

(1)static synchronized是类锁,锁住这个类

Java并发编程_synchronized关键字的用法(一)的更多相关文章

  1. Java并发编程_volatile关键字的用法(二)

    被volatile修饰的变量能够保证每个线程能够获取该变量的最新值,从而避免出现数据脏读的现象. 根据下面实例理解: package sync; public class VolatileTest e ...

  2. Java并发编程 Volatile关键字解析

    volatile关键字的两层语义 一旦一个共享变量(类的成员变量.类的静态成员变量)被volatile修饰之后,那么就具备了两层语义: 1)保证了不同线程对这个变量进行操作时的可见性,即一个线程修改了 ...

  3. Java并发编程1--synchronized关键字用法详解

    1.synchronized的作用 首先synchronized可以修饰方法或代码块,可以保证同一时刻只有一个线程可以执行这个方法或代码块,从而达到同步的效果,同时可以保证共享变量的内存可见性 2.s ...

  4. Java并发编程volatile关键字

    volatile理解 Java语言是支持多线程的,为了解决线程并发的问题,在语言内部引入了 同步块 和volatile 关键字机制.volatile具有synchronized关键字的“可见性”,vo ...

  5. java并发编程 volatile关键字 精准理解

    1.volatile的作用 一个线程共享变量(类的成员变量.类的静态成员变量等)被volatile修饰之后,就具有以下作用: 1)并发中的变量可见性(不同线程对该变量进行操作时的可见性),即一个线程修 ...

  6. Java并发编程:volatile关键字解析

    Java并发编程:volatile关键字解析 volatile这个关键字可能很多朋友都听说过,或许也都用过.在Java 5之前,它是一个备受争议的关键字,因为在程序中使用它往往会导致出人意料的结果.在 ...

  7. (转)Java并发编程:volatile关键字解析

    转:http://www.cnblogs.com/dolphin0520/p/3920373.html Java并发编程:volatile关键字解析 volatile这个关键字可能很多朋友都听说过,或 ...

  8. Java并发编程:volatile关键字解析(转载)

    转自https://www.cnblogs.com/dolphin0520/p/3920373.html Java并发编程:volatile关键字解析   Java并发编程:volatile关键字解析 ...

  9. Java并发编程学习:volatile关键字解析

    转载:https://www.cnblogs.com/dolphin0520/p/3920373.html 写的非常棒,好东西要分享一下 Java并发编程:volatile关键字解析 volatile ...

随机推荐

  1. Netty实现简易http_server

    Netty可以通过一些handler实现简单的http服务器.具体有三个类,分别是HttpServer.java.ServerHandlerInit.java.BusiHandler.java. 具体 ...

  2. Mongodb 分享(一)

    Mongodb使用基础知识: 一.简介 1.mongodb是什么? 1)MongoDB 是一个基于分布式文件存储的数据库.由 )mongodb 客户端:NoSQL Manager for MongoD ...

  3. pandas的时间戳

    pandas时间: p1=pd.Timestamp(2018, 2, 3) p1输出:2018-02-03 00:00:00 p1输出类型:<class 'pandas._libs.tslib. ...

  4. pre打印

    echo "<pre>";print_r(var);echo "</pre>";

  5. LOJ6072苹果树

    虽然结合了很多算法,但是一步一步地推一下还不算太难的一道题. 首先考虑枚举枚举有用的苹果的集合,然后去算生成树个数. 先考虑怎么计算生成树个数. 发现可以使用matrix-tree. 所有有用点可以和 ...

  6. CentOS6.8下实现配置配额

    CentOS6.8下实现配置配额 Linux系统是支持多用户的,即允许多个用户同时使用linux系统,普通用户在/home/目录下均有自己的家目录,在默认状态下,各个用户可以在自己的家目录下任意创建文 ...

  7. python记录_day15 面向对象初识

    一.面向过程和面向对象 1.面向过程 以我为中心,做一件事先干什么,在干什么,后干什么,有一套清楚完整的流程.核心是“过程”. 优点:将要解决的问题流程化, 编写相对简单 缺点:可扩展性差 2.面向对 ...

  8. csrf漏洞

    漏洞原理:csrf全名为跨站请求伪造,是一种对网站的恶意利用,虽然听起来和xss很像,但是它们俩还是有很大的区别的.csrf是通过伪造来自受信任用户的请求来利用受信任的网站. 比如: 一个有csrf漏 ...

  9. virtualbox不能安装64位操作系统

    现在virtualbox 还是比较好用的虚拟机.新建立一个不同的操作系统还是非常方便. virtualbox下载地址  https://www.virtualbox.org/wiki/Download ...

  10. [LeetCode] 104. Maximum Depth of Binary Tree ☆(二叉树的最大深度)

    描述 Given a binary tree, find its maximum depth. The maximum depth is the number of nodes along the l ...