一、多个对象多把锁

例子代码:

package com.lhy.thread01;

public class MultiThread {

    //static
private int num = 0; //加上static后就是类级别的锁。不加,是对象级别的锁,此时多个线程之间是互不干扰
public synchronized void printNum(String tag){
try{
if("a".equals(tag)){
num = 100;
System.out.println("tag a ,set num over!");
Thread.sleep(1000);//a会睡1秒,b不会
}else{
num = 200;
System.out.println("tag b ,set num over!");
}
System.out.println("tag "+ tag +" , num = "+ num);
}catch(Exception e){
e.printStackTrace();
}
} public static void main(String[] args) {
//两个不同的对象
final MultiThread m1 = new MultiThread();
final MultiThread m2 = new MultiThread(); Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
m1.printNum("a");
}
}); Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
m2.printNum("b");
}
}); t1.start();
t2.start();
} }

执行结果:

关键字synchornized获得的锁是对象锁,哪个线程先执行synchornized关键字的方法,哪个线程就持有该方法所属对象的锁,例子程序中,由于m1和m2是两个不同的对象,t1 线程获得 m1对象的锁,t2线程获得m2对象的锁,所以互不影响。

验证, 如果将main方法改为如下所示,t1 和 t2 线程都执行m1对象的printNum方法,此时两个线程在抢一把锁,所以执行会按顺序来:

public static void main(String[] args) {
//两个不同的对象
final MultiThread m1 = new MultiThread();
//final MultiThread m2 = new MultiThread(); Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
m1.printNum("a");
}
}); Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
m1.printNum("b");
}
}); t1.start();
t2.start();
}

二、多个对象一把锁(类锁)

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

例子程序:

public class MultiThread {

    //static
private static int num = 0; //加上static后就是类级别的锁。不加,是对象级别的锁,此时多个线程之间是互不干扰
public static synchronized void printNum(String tag){
try{
if("a".equals(tag)){
num = 100;
System.err.println("tag a ,set num over!");
Thread.sleep(1000);//a会睡1秒,b不会
}else{
num = 200;
System.err.println("tag b ,set num over!");
}
System.err.println("tag "+ tag +" , num = "+ num);
}catch(Exception e){
e.printStackTrace();
}
} public static void main(String[] args) {
//两个不同的对象
final MultiThread m1 = new MultiThread();
final MultiThread m2 = new MultiThread(); Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
m1.printNum("a");
}
}); Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
m2.printNum("b");
}
}); t1.start();
t2.start();
} }

执行结果:

是按照t1、t2 顺序执行的。

线程安全-002-多个线程多把锁&类锁的更多相关文章

  1. Android线程管理之ThreadPoolExecutor自定义线程池

    前言: 上篇主要介绍了使用线程池的好处以及ExecutorService接口,然后学习了通过Executors工厂类生成满足不同需求的简单线程池,但是有时候我们需要相对复杂的线程池的时候就需要我们自己 ...

  2. 【转】线程及同步的性能 - 线程池 / ThreadPoolExecutors / ForkJoinPool

    线程池和ThreadPoolExecutors 虽然在程序中可以直接使用Thread类型来进行线程操作,但是更多的情况是使用线程池,尤其是在Java EE应用服务器中,一般会使用若干个线程池来处理来自 ...

  3. java多线程系类:JUC线程池:05之线程池原理(四)(转)

    概要 本章介绍线程池的拒绝策略.内容包括:拒绝策略介绍拒绝策略对比和示例 转载请注明出处:http://www.cnblogs.com/skywang12345/p/3512947.html 拒绝策略 ...

  4. java多线程系类:JUC线程池:03之线程池原理(二)(转)

    概要 在前面一章"Java多线程系列--"JUC线程池"02之 线程池原理(一)"中介绍了线程池的数据结构,本章会通过分析线程池的源码,对线程池进行说明.内容包 ...

  5. java多线程系类:JUC线程池:02之线程池原理(一)

    在上一章"Java多线程系列--"JUC线程池"01之 线程池架构"中,我们了解了线程池的架构.线程池的实现类是ThreadPoolExecutor类.本章,我 ...

  6. java多线程系类:JUC线程池:01之线程池架构

    概要 前面分别介绍了"Java多线程基础"."JUC原子类"和"JUC锁".本章介绍JUC的最后一部分的内容--线程池.内容包括:线程池架构 ...

  7. iOS开发:(线程篇-上)线程和进程

    iOS开发多线程篇—多线程简单介绍 一.进程和线程 1.什么是进程 进程是指在系统中正在运行的一个应用程序 每个进程之间是独立的,每个进程均运行在其专用且受保护的内存空间内 比如同时打开QQ.Xcod ...

  8. java 22 - 18 多线程之 线程的状态转换、线程组

    线程的状态转换图解:图片 线程的线程组: 线程组: 把多个线程组合到一起.    它可以对一批线程进行分类管理,Java允许程序直接对线程组进行控制. 首先创建一个Runnable的实现类 publi ...

  9. 突破python缺陷,实现几种自定义线程池 以及进程、线程、协程的介绍

    Python线程 Threading用于提供线程相关的操作,线程是应用程序中工作的最小单元. #!/usr/bin/env python # -*- coding:utf-8 -*- import t ...

随机推荐

  1. KALI安装与环境配置

    2018-2019 201899224<网络攻防实践>第二周作业 虚拟化网络攻防实验环境包括以下部分: 靶机:包含系统和应用程序安全漏洞,并作为攻击目标的主机.(Windows XP和Li ...

  2. TZOJ 4244 Sum(单调栈区间极差)

    描述 Given a sequence, we define the seqence's value equals the difference between the largest element ...

  3. 团队项目NABCD分析

    1.卡片分类讨论 我们团队在软件工程课上对准备开发的帮你项目进行激烈的讨论后,得出了两个特点. (1)信息检索 (2)主动推送 之所以得出这两个特点,是因为我们作为学生,平常在校园里面有很多专用群和Q ...

  4. [leetcode]380. Insert Delete GetRandom O(1)常数时间插入删除取随机值

    Design a data structure that supports all following operations in average O(1) time. insert(val): In ...

  5. git 使用遇到的问题

    本博客只记录遇到的问题和解决方案 问题一:git上与本地不同步无法上传 先git pull origin master再git push -u origin master(实在不行或者清空本地,或者清 ...

  6. Js学习(3) 数组

    数组本质: 本质上数组是特殊的对象,因此,数组中可以放入任何类型的数据,对象,数组,函数都行 它的特殊性在于键名是按次序排列好的整数 从0开始,是固定的,不用指定键名 如果数组中的元素仍是数组,则为多 ...

  7. Vim中YouCompleteMe插件安装

    背景 YouCompleteMe需要使用GCC进行编译,然而Centos 6.7默认的GCC版本太低,所以需要使用devtools-2,用来安装多个版本GCC手动编译安装GCC的坑简直不要太多(类似于 ...

  8. 6E - 寒冰王座

    不死族的巫妖王发工资拉,死亡骑士拿到一张N元的钞票(记住,只有一张钞票),为了防止自己在战斗中频繁的死掉,他决定给自己买一些道具,于是他来到了地精商店前. 死亡骑士:"我要买道具!" ...

  9. PostFix添加多个端口

    /usr/local/*/config/postfix/master.cf 在/etc/services中搜索smtp,复制,添加smtp2<与上面一步对应起来的服务名>,后面为需要添加的 ...

  10. Spring遇到的问题合集

    2018-09-15 元素 "tx:annotation-driven" 的前缀 "tx" 未绑定. 后来我加了 http://www.springframew ...