synchronized使用之基本原则:

synchronized可以锁方法,也可以锁代码片段,但要实现互斥的基本就是在想要互斥的代码上加”同一把锁“,也就是同一个对象,也就是用==判断等于true的对象

下面看一个例子:

Work.java    真正做事情的类

 package com.yzl;

 public class Work {
/**
* 未同步的
* @param name
*/
public void noSynwrite(String name){
for(int i=0; i<name.length(); i++){
System.out.print(name.charAt(i));
if(i == (name.length()-1)){
System.out.print("\n");
}
}
} /**
* 使用同步块,并使用Work的实例对象做为锁
* 此方法的同步需保证是调用该方法的work对象是同一个
* @param name
*/
public void write1(String name){
synchronized (this) {
for(int i=0; i<name.length(); i++){
System.out.print(name.charAt(i));
if(i == (name.length()-1)){
System.out.print("\n");
}
}
}
} /**
* 使用同步块,并使用Work的字节码做为锁
* @param name
*/
public void write1WithStatic(String name){
synchronized (Work.class) {
for(int i=0; i<name.length(); i++){
System.out.print(name.charAt(i));
if(i == (name.length()-1)){
System.out.print("\n");
}
}
}
} /**
* 使用同步的方法,锁对象为ork的实例对象
* 此方法的同步需保证是调用该方法的work对象是同一个
* @param name
*/
public synchronized void write2(String name){
for(int i=0; i<name.length(); i++){
System.out.print(name.charAt(i));
if(i == (name.length()-1)){
System.out.print("\n");
}
}
} /**
* 静态方法的同步方法,同步的对象是对象的字节码,也就是Work.class
* 如果要与上面的方法一起使用并保持互斥,则可以把write1的锁对象this改成Work.class
* @param name
*/
public synchronized static void write3(String name){
for(int i=0; i<name.length(); i++){
System.out.print(name.charAt(i));
if(i == (name.length()-1)){
System.out.print("\n");
}
}
}
}

测试类ThreadPart_2.java

 package com.yzl;

 /**
* 传统的线程互斥
* 原理:使用同一个对象(锁)才能实现,
* 静态方法的同步则只能使用类的字节码也就是ClassName.class来做锁
* @author yzl
*
*/
public class ThreadPart_2 {
public static void main(String[] args) {
noSyn();
synWithOneObj();
synWithOneStaticObj();
} /**
* 未线程同步的
*/
private static void noSyn(){
final Work work = new Work(); Thread thread = new Thread(new Runnable() {
@Override
public void run() {
while(true){
work.noSynwrite("wangwu");
}
}
});
thread.start(); Thread thread1 = new Thread(new Runnable() {
@Override
public void run() {
while(true){
work.noSynwrite("zhangsan");
}
}
});
thread1.start();
} /**
* 使用同一个实例对象做为锁的
*/
private static void synWithOneObj(){
final Work work = new Work(); Thread thread = new Thread(new Runnable() {
@Override
public void run() {
while(true){
work.write1("wangwu");
}
}
});
thread.start(); Thread thread1 = new Thread(new Runnable() {
@Override
public void run() {
while(true){
work.write2("zhangsan");
}
}
});
thread1.start();
} /**
* 使用同一个类的字节码做为锁的
*/
private static void synWithOneStaticObj(){
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
while(true){
new Work().noSynwrite("wangwu");
}
}
});
thread.start(); Thread thread1 = new Thread(new Runnable() {
@Override
public void run() {
while(true){
Work.write3("zhangsan");
}
}
});
thread1.start();
}
}

将上面ThreadPart_2的第12、13、14行代码分别依次执行,

第12行代码将出现如下类似结果:

//运行结果部分示例
zhangsan
zhwu
wangwu
wangangsan
zhangsawangwu

第13和14行将是正常的打印各自的名字

2、传统的线程互斥synchronized的更多相关文章

  1. 传统的线程互斥技术:Synchronized关键字

    多个线程操作同一个方法或变量时常常出现错误,要保证每个线程都正常运行就要通过加锁,每次只有一个能够拿到锁通过.如下: package cn.sp.thread; /** * Created by 2Y ...

  2. 线程互斥synchronized

    /** * * 线程互斥,采用synchronized关键字可以实现线程与线程之间的互斥,要注意的是在synchronized上的对象要是同一个,才可以 * 保证在同一时刻,只有一个线程可以执行syn ...

  3. 【Java并发专题之三】Java线程互斥、协作原理

    (I)Java线程互斥原理之synchronized原理 从JDK5引入CAS原子操作,但没有对synchronized关键字做优化,而是增加了J.U.C.concurrent,concurrent包 ...

  4. 【原】iOS多线程之线程间通信和线程互斥

    线程间通信 1> 线程间通信分为两种 主线程进入子线程(前面的方法都可以) 子线程回到主线程 2> 返回主线程 3> 代码 这个案例的思路是:当我触摸屏幕时,会在子线程加载图片,然后 ...

  5. java线程安全— synchronized和volatile

    java线程安全— synchronized和volatile package threadsafe; public class TranditionalThreadSynchronized { pu ...

  6. java多线程与线程并发二:线程互斥

    本文章内容整理自:张孝祥_Java多线程与并发库高级应用视频教程 当两条线程访问同一个资源时,可能会出现安全隐患.以打印字符串为例,先看下面的代码: // public class Test2 { p ...

  7. Java线程同步synchronized的理解

    JVM中(留神:马上讲到的这两个存储区只在JVM内部与物理存储区无关)存在一个主内存(Main Memory),Java中所有的变量存储在主内存中,所有实例和实例的字段都在此区域,对于所有的线程是共享 ...

  8. GIL与线程互斥锁

    GIL 是解释器级别的锁,是限制只有一个原生线程运行,防止多个原生线程之间修改底层的共享数据.而线程互斥锁是防止多个线程同时修改python内存空间的共享数据.

  9. C#中的多线程与线程互斥

    通过多线程,C#可以并行地执行代码. 每一个线程都有它独立的执行路径,所有线程都能访问共有变量. 这就引发了线程竞争 这时就需要使用线程安全的处理方式使得线程互斥 先来看一段多线程代码 using S ...

随机推荐

  1. JMap与JStack

    用JMap和JStack做堆dump和线程dump 命令 1. jmap -dump:format=b,file=filename pidjmap -dump:format=b,file=jmap02 ...

  2. 6.2 dubbo在spring中自定义xml标签源码解析

    在6.1 如何在spring中自定义xml标签中我们看到了在spring中自定义xml标签的方式.dubbo也是这样来实现的. 一 META_INF/dubbo.xsd 比较长,只列出<dubb ...

  3. Python/Shell 正则表达式与运用

    正则表达式用的地方是很多的.比如字符串处理过程中.最近遇到记录一下. 1. 比如在shell中 #!/bin/bash str="date:2017-11-28 os:centos blac ...

  4. [leetcode]Pascal's Triangle II @ Python

    原题地址:https://oj.leetcode.com/problems/pascals-triangle-ii/ 题意: Given an index k, return the kth row ...

  5. Safari不兼容Javascript中的Date问题

    在IOS5以上版本(不包含IOS5)中的Safari浏览器能正确解释出Javascript中的 new Date('2013-10-21') 的日期对象,但是在IOS5版本里面的Safari解释new ...

  6. Android教材 | 第三章 Android界面事件处理(一)—— 杰瑞教育原创教材试读

      前  言 JRedu Android应用开发中,除了界面编程外,另一个重要的内容就是组件的事件处理.在Android系统中,存在多种界面事件,比如触摸事件.按键事件.点击事件等.在用户交互过程中, ...

  7. mongoose系列——几行代码实现CRUD

    1. nodejs 确实好用,mongoose封装了mongodb,代码很简洁. const mongoose = require('mongoose'); mongoose.connect(&quo ...

  8. Docker登录失败

      % docker login Username: xxxx Password: Email: xxxxxxx@yahoo.co.jp FATA[0033] Error response from ...

  9. $(...).modal is not a function

    bootstrap中调用$(...).modal 方法 提示一个错误 is not a function 检查HTML结构发现,是因为使用了多个Jquery版本,产生了冲突. 解决办法:删掉一个Jqu ...

  10. Spring 集成 redistemplate

    jar包 <version.clients.jedis>2.7.2</version.clients.jedis><version.data.redis>1.6.2 ...