线程安全-002-多个线程多把锁&类锁
一、多个对象多把锁
例子代码:
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-多个线程多把锁&类锁的更多相关文章
- Android线程管理之ThreadPoolExecutor自定义线程池
前言: 上篇主要介绍了使用线程池的好处以及ExecutorService接口,然后学习了通过Executors工厂类生成满足不同需求的简单线程池,但是有时候我们需要相对复杂的线程池的时候就需要我们自己 ...
- 【转】线程及同步的性能 - 线程池 / ThreadPoolExecutors / ForkJoinPool
线程池和ThreadPoolExecutors 虽然在程序中可以直接使用Thread类型来进行线程操作,但是更多的情况是使用线程池,尤其是在Java EE应用服务器中,一般会使用若干个线程池来处理来自 ...
- java多线程系类:JUC线程池:05之线程池原理(四)(转)
概要 本章介绍线程池的拒绝策略.内容包括:拒绝策略介绍拒绝策略对比和示例 转载请注明出处:http://www.cnblogs.com/skywang12345/p/3512947.html 拒绝策略 ...
- java多线程系类:JUC线程池:03之线程池原理(二)(转)
概要 在前面一章"Java多线程系列--"JUC线程池"02之 线程池原理(一)"中介绍了线程池的数据结构,本章会通过分析线程池的源码,对线程池进行说明.内容包 ...
- java多线程系类:JUC线程池:02之线程池原理(一)
在上一章"Java多线程系列--"JUC线程池"01之 线程池架构"中,我们了解了线程池的架构.线程池的实现类是ThreadPoolExecutor类.本章,我 ...
- java多线程系类:JUC线程池:01之线程池架构
概要 前面分别介绍了"Java多线程基础"."JUC原子类"和"JUC锁".本章介绍JUC的最后一部分的内容--线程池.内容包括:线程池架构 ...
- iOS开发:(线程篇-上)线程和进程
iOS开发多线程篇—多线程简单介绍 一.进程和线程 1.什么是进程 进程是指在系统中正在运行的一个应用程序 每个进程之间是独立的,每个进程均运行在其专用且受保护的内存空间内 比如同时打开QQ.Xcod ...
- java 22 - 18 多线程之 线程的状态转换、线程组
线程的状态转换图解:图片 线程的线程组: 线程组: 把多个线程组合到一起. 它可以对一批线程进行分类管理,Java允许程序直接对线程组进行控制. 首先创建一个Runnable的实现类 publi ...
- 突破python缺陷,实现几种自定义线程池 以及进程、线程、协程的介绍
Python线程 Threading用于提供线程相关的操作,线程是应用程序中工作的最小单元. #!/usr/bin/env python # -*- coding:utf-8 -*- import t ...
随机推荐
- swift 警告框 - 自定义按钮颜色,图片
1.封装 弹框http://www.hangge.com/blog/cache/detail_651.html import UIKit extension UIAlertController { / ...
- [leetcode]23. Merge k Sorted Lists归并k个有序链表
Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity. I ...
- git基本
基本的git操作 git config --global user.name "你的名字或昵称" git config --global user.email "你的邮箱 ...
- Django haystack+solr搜索引擎部署的坑.
跟着<<Django by Example>> 一路做下来,到了搭建搜索引擎的步骤 默认的思路是用 obj.objects.filter(body__icontains='fr ...
- RQNOJ 3 Jam的计数法
一道模拟题,用的vector比用链表要方便很多,毕竟不需要自己写,因为是递增的,所以每一次你都要去检查最后一位加1之后有没有越界,如果没越界你就可以把他当前的字符删掉替换成他下一位的字符就可以了,如果 ...
- selenium+java+chrome 自动化测试环境搭建
安装jdk (jdk 配置环境变量) eclipse(可用免安装的) 安装谷歌浏览器 下载chorme driver (chorme driver 也要配置环境变量,将chormedriv ...
- Effective C++ 笔记:条款 31 将编译关系降至最低
31 : Minimize compilation dependencies between files 1 这关乎C++的类(或说都是类惹的祸) 1.1 C++类定义式的问题 C++类定义式不只叙述 ...
- Office365 Manager Plus之报表
Office365 Manager Plus之报表 也许您刚刚开始使用Office 365,对它的各个组件还有很多疑问,如何快速掌握Office 365各种服务的用法?如何管理邮箱?如何监控邮件流量? ...
- centos7 go ENV 部署
1.wget官网下载go 官网https://golang.org/dl/ 2.解压 tar -C /usr/local -xzf go$VERSION.$OS-$ARCH.tar.gz 3.配置环境 ...
- javascript字符串方法总结
一.单引号字符串内部可以使用双引号,双引号字符串内部也可以使用单引号 "hello 'world'" 'welcome "to" js' 二.多行和转义 如果要 ...