常见三种使用方式

1)普通同步方法,锁是当前实例;
2)静态同步方法,锁是当前类的Class实例,Class数据存在永久代中,是该类的一个全局锁;
3)对于同步代码块,锁是synchronized括号里配置的对象。

方式一   普通方法通过synchronized修饰

1)不采用synchronized     当创建两个线程对象  线程t1  t2中采用同一个实例化类对象  调用method方法  会交异步执行  互补影响

package cn.ac.bcc.sync;
/**
* 普通同步方法通过synchronized修饰
* @author Administrator
*
*/
public class PtMethod { /**
* 1)不采用synchronized修饰
* @param s
*/
public void method(String s){
if(s.equals("a")){
System.out.println(Thread.currentThread().getName()+": a"); try {
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}else{
System.out.println(Thread.currentThread().getName()+": b");
}
} public static void main(String[] args) {
//创建当前类对象实例
final PtMethod ptMethod = new PtMethod(); //创建线程
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
ptMethod.method("a");
}
}); Thread t2 = new Thread(new Runnable(){
@Override
public void run() {
// TODO Auto-generated method stub
ptMethod.method("b");
} }); t1.start();
t2.start();
} }

运行结果:

Thread-1: b
Thread-0: a

2)采用synchronized   当创建两个线程对象  线程t1 t2 中采用同一个实例化对象  调用synchronized修饰的method方法  method方法中线程睡眠一秒钟  当线程t1优先抢占到method方法的执行权时由于method方法被synchronized修饰  method方法被实例化对象ptMethod对象锁锁住   当t2线程同样是ptMethod实例化对象调用当前method方法 由于两个线程t1 t2 都采用的是同一个实例化对象ptMethod 对象锁 只有t1运行完成后  t2中线程中的ptMethod对象才能调用method方法。由于method中获取当前调用线程睡眠  t2要等t1中调用的method睡眠唤醒之后执行完方法才能执行。

public class PtMethod {

    /**
* 1)采用synchronized修饰
* @param s
*/
public synchronized void method(String s){
if(s.equals("a")){
System.out.println(Thread.currentThread().getName()+": a"); try {
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}else{
System.out.println(Thread.currentThread().getName()+": b");
}
} public static void main(String[] args) {
//创建当前类对象实例
final PtMethod ptMethod = new PtMethod(); //创建线程
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
ptMethod.method("a");
}
}); Thread t2 = new Thread(new Runnable(){
@Override
public void run() {
// TODO Auto-generated method stub
ptMethod.method("b");
} }); t1.start();
t2.start();
} }

3)采用synchronized修饰   创建两个线程对象  创建当前类实例对象 ptMethod1 ptMethod2  t1线程运行ptMetod1    t2线程运行ptMethod2 对象分别调用mehod方法  运行结果如下 ,由于两个线程分别采用的是两个不同的实例对象  当两个实例对象调用method方法时  synchronized判断当前锁对象并不相同  所以里两个对象向都分别调用了method方法,而不需要等待

public class PtMethod {

    /**
* 1)采用synchronized修饰
* @param s
*/
public synchronized void method(String s){
if(s.equals("a")){
System.out.println(Thread.currentThread().getName()+": a"); try {
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}else{
System.out.println(Thread.currentThread().getName()+": b");
}
} public static void main(String[] args) {
//创建当前类对象实例
final PtMethod ptMethod1 = new PtMethod();
final PtMethod ptMethod2 = new PtMethod(); //创建线程
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
ptMethod1.method("a");
}
}); Thread t2 = new Thread(new Runnable(){
@Override
public void run() {
// TODO Auto-generated method stub
ptMethod2.method("b");
} }); t1.start();
t2.start();
} }

运行结果:

Thread-0: a

Thread-1: b

二、synchronized修饰静态方法
采用synchronized  修饰的静态方法  两个线程通过不同的  类实例对象调用  这个方法  如何加锁  这是可以将该方法修改为static 方法  并synchronized修饰

public class SyncDemo {

    /**
* 类方法 synchronized修饰 解决多个线程调用当前类不同实例采用同步锁方法
* @param s
*/
public static synchronized void method(String s){ if(s.equals("a")){
System.out.println(Thread.currentThread().getName()+": a"); try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}else{
System.out.println(Thread.currentThread().getName()+": b");
}
} public static void main(String[] args) { final SyncDemo syncDemo1 = new SyncDemo();
final SyncDemo syncDemo2 = new SyncDemo(); Thread t1 = new Thread(new Runnable() { @Override
public void run() {
// TODO Auto-generated method stub
syncDemo1.method("a");
}
}); Thread t2 = new Thread(new Runnable(){ @Override
public void run() {
// TODO Auto-generated method stub
syncDemo2.method("b");
}});
t1.start();
t2.start();
}
}

三、同步代码块

1)当两个并发线程同时访问一个对象的同步代码块synchronized(this),在某一时刻只有一条线程才能访问该同步代码块

public class SyncDemo1 implements Runnable {

    public static void main(String[] args) {

        SyncDemo1 syncDemo1 = new SyncDemo1();
new Thread(syncDemo1,"a").start();;
new Thread(syncDemo1,"b").start();;
} @Override
public void run() {
// TODO Auto-generated method stub
System.out.println(Thread.currentThread().getName()+"执行开始run方法");
synchronized (this) {
System.out.println(Thread.currentThread().getName());
}
} }

运行结果:  当b抢到执行权只有b线程执行完成a线程才能继续执行

b执行开始run方法
b
a执行开始run方法
a

2)当一个线程访问object对象中的synchronized(this)同步代码块时,另一个线程可以访问object对象的非同步代码块

package cn.ac.bcc.sync;

public class SyncDemo2 {

    public void method1(){
synchronized (this) {
System.out.println(Thread.currentThread().getName()+"线程同步代码块");
}
} public void method2(){
System.out.println(Thread.currentThread().getName()+"当两个线程访问同一个object 中的方法 一个线程访问线程同步方法 另一个可以方位object对象的非线程同步方法");
} public static void main(String[] args) { final SyncDemo2 syncDemo2 = new SyncDemo2(); //创建两个线程对象
Thread t1 = new Thread(new Runnable() { @Override
public void run() {
// TODO Auto-generated method stub
syncDemo2.method1();
}
},"t1"); Thread t2 = new Thread(new Runnable(){ @Override
public void run() {
// TODO Auto-generated method stub
syncDemo2.method2();
} },"t2"); t1.start();
t2.start(); }
}

3)当一个线程访问object的一个synchronized(this)同步代码块时,其他线程对object中所有其它synchronized(this)同步代码块的访问将被阻塞。

package cn.ac.bcc.sync;

public class SyncDemo2 {

    public void method1(){
synchronized (this) {
System.out.println(Thread.currentThread().getName()+"线程同步代码块");
try {
System.out.println(Thread.currentThread().getName()+"睡一会");
Thread.sleep(10000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
} public void method2(){ synchronized (this) {
System.out.println(Thread.currentThread().getName()+"访问线程同步代码块");
}
} public static void main(String[] args) { final SyncDemo2 syncDemo2 = new SyncDemo2(); //创建两个线程对象
Thread t1 = new Thread(new Runnable() { @Override
public void run() {
// TODO Auto-generated method stub
syncDemo2.method1();
}
},"t1"); Thread t2 = new Thread(new Runnable(){ @Override
public void run() {
// TODO Auto-generated method stub
syncDemo2.method2();
} },"t2"); t1.start();
t2.start(); }
}

运行结果:

t1线程同步代码块
t1睡一会

10秒后t2才能访问当前对象其他同步代码块修饰的方法

t1线程同步代码块
t1睡一会
t2访问线程同步代码块

synchronized 基本用法的更多相关文章

  1. Java中Synchronized的用法

    原文:http://blog.csdn.net/luoweifu/article/details/46613015 作者:luoweifu 转载请标名出处 <编程思想之多线程与多进程(1)——以 ...

  2. Synchronized的用法

    synchronized是Java中的关键字,是一种同步锁.它修饰的对象有以下几种: 1. 修饰一个代码块,被修饰的代码块称为同步语句块,其作用的范围是大括号{}括起来的代码,作用的对象是调用这个代码 ...

  3. 巨人大哥谈Java中的Synchronized关键字用法

    巨人大哥谈Java中的Synchronized关键字用法 认识synchronized 对于写多线程程序的人来说,经常碰到的就是并发问题,对于容易出现并发问题的地方价格synchronized基本上就 ...

  4. synchronized关键字用法

    看到网上很多讲synchronized关键字用法的文章,说的都很有道理,也很深刻,但是看完总感觉脑袋里还是有点乱乱的.经过一番自己的思考后,想从自己的思考角度出发,来说一说synchronized关键 ...

  5. Java 中 synchronized的用法详解(四种用法)

    Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码.本文给大家介绍java中 synchronized的用法,对本文感兴趣的朋友一起看看吧 ...

  6. 【转】Java中Synchronized的用法

    <编程思想之多线程与多进程(1)——以操作系统的角度述说线程与进程>一文详细讲述了线程.进程的关系及在操作系统中的表现,这是多线程学习必须了解的基础.本文将接着讲一下Java线程同步中的一 ...

  7. iOS 线程安全之@synchronized的用法

    @synchronized(self)的用法: @synchronized 的作用是创建一个互斥锁,保证此时没有其它线程对self对象进行修改.这个是objective-c的一个锁定令牌,防止self ...

  8. Java synchronized关键字用法(清晰易懂)

    本篇随笔主要介绍 java 中 synchronized 关键字常用法,主要有以下四个方面: 1.实例方法同步 2.静态方法同步 3.实例方法中同步块 4.静态方法中同步块 我觉得在学习synchro ...

  9. java中synchronized的用法详解

    记下来,很重要. Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码. 一.当两个并发线程访问同一个对象object中的这个synchron ...

  10. synchronized Lock用法

    在介绍Lock与synchronized时,先介绍下Lock: public interface Lock { void lock(); void lockInterruptibly() throws ...

随机推荐

  1. input和textarea修改placeholder颜色和字号

    方式1因为每个浏览器的CSS选择器都有所差异,所以需要针对每个浏览器做单独的设定(可以在冒号前面写input和textarea).::-webkit-input-placeholder { /* We ...

  2. 【Shell脚本学习22】Shell 函数:Shell函数返回值、删除函数、在终端调用函数

    函数可以让我们将一个复杂功能划分成若干模块,让程序结构更加清晰,代码重复利用率更高.像其他编程语言一样,Shell 也支持函数.Shell 函数必须先定义后使用. Shell 函数的定义格式如下: f ...

  3. 用log4net快速构建asp.net 异常日志

    log4net是一个非常完善的日志组件. 有着强大的可配置性. 有助于提高开发效率 .log4net是apache组织开发的日志组件, 同其姐妹log4j一样, 是一个开源项目. 可以以插件的形式应用 ...

  4. vue的MVVM模式和生命周期总结(一)

    一.MVVM模式 MVVM 是Model-View-ViewModel 的缩写,它是一种基于前端开发的架构模式,其核心是提供对View 和 ViewModel 的双向数据绑定,这使得ViewModel ...

  5. 解决IE下面诡异地使用quickrIE5模式打开页面的有关问题

    解决IE下面诡异地使用quickrIE5模式打开页面的有关问题 <!doctype html public "-//w3c//dtd html 4.01 transitional//e ...

  6. MySQL设计规范与性能优化

    引言 MySQL是目前使用最为广泛的关系型数据库之一,如果使用得当,可支撑企业级高并发.高可靠服务,使用不当甚至连并发量略高的个人网站都难以支撑: 就算使用了缓存,大量的数据库访问依旧在所难免,即使设 ...

  7. 2017.12.20 Java中的 IO/XML学习总结 File类详细

    IO / XML 一.File类 1.定义/概念 Java是面向对象的语言,要想把数据存到文件中,就必须要有一个对象表示这个文件.File类的作用就是代表一个特定的文件或目录,并提供了若干方法对这些文 ...

  8. display:inline-block解决文字有间隙问题

    定义:display:inline-block是使元素以块级元素的形式呈现在行内.意思就是说,让这个元素显示在同一行不换行,但是又可以控制高度和宽度,这相当于内联元素的增强. 但是display:in ...

  9. windows下安装win7虚拟机并安装oracle

    一.win7虚拟机 与安装linux虚拟机没有什么不同,不同的是选择客户机操作系统.内存.磁盘容量,以及映像文件. 创建win7虚拟机步骤简化: 新建虚拟机-->>自定义-->> ...

  10. SVG path

    在网页上画一图形,比如星星或波浪线,开始是想着图形软件画一个的,后来发现SVG这绘图程序的语言,感觉甚是可以,就发了些时间学了一下,在此做一简单分享和记录. 菜鸟上是这么介绍的(SVG 是使用 XML ...