• 2、传统的线程互斥synchronized


    synchronized使用之基本原则:

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

    下面看一个例子:

    Work.java    真正做事情的类

     1 package com.yzl;
     2 
     3 public class Work {
     4     /**
     5      * 未同步的
     6      * @param name
     7      */
     8     public void noSynwrite(String name){
     9         for(int i=0; i<name.length(); i++){
    10             System.out.print(name.charAt(i));
    11             if(i == (name.length()-1)){
    12                 System.out.print("
    ");
    13             }
    14         }
    15     }
    16     
    17     /**
    18      * 使用同步块,并使用Work的实例对象做为锁
    19      * 此方法的同步需保证是调用该方法的work对象是同一个
    20      * @param name
    21      */
    22     public void write1(String name){
    23         synchronized (this) {
    24             for(int i=0; i<name.length(); i++){
    25                 System.out.print(name.charAt(i));
    26                 if(i == (name.length()-1)){
    27                     System.out.print("
    ");
    28                 }
    29             }
    30         }
    31     }
    32     
    33     /**
    34      * 使用同步块,并使用Work的字节码做为锁
    35      * @param name
    36      */
    37     public void write1WithStatic(String name){
    38         synchronized (Work.class) {
    39             for(int i=0; i<name.length(); i++){
    40                 System.out.print(name.charAt(i));
    41                 if(i == (name.length()-1)){
    42                     System.out.print("
    ");
    43                 }
    44             }
    45         }
    46     }
    47     
    48     /**
    49      * 使用同步的方法,锁对象为ork的实例对象
    50      * 此方法的同步需保证是调用该方法的work对象是同一个
    51      * @param name
    52      */
    53     public synchronized void write2(String name){
    54         for(int i=0; i<name.length(); i++){
    55             System.out.print(name.charAt(i));
    56             if(i == (name.length()-1)){
    57                 System.out.print("
    ");
    58             }
    59         }
    60     }
    61     
    62     /**
    63      * 静态方法的同步方法,同步的对象是对象的字节码,也就是Work.class
    64      * 如果要与上面的方法一起使用并保持互斥,则可以把write1的锁对象this改成Work.class
    65      * @param name
    66      */
    67     public synchronized static void write3(String name){
    68         for(int i=0; i<name.length(); i++){
    69             System.out.print(name.charAt(i));
    70             if(i == (name.length()-1)){
    71                 System.out.print("
    ");
    72             }
    73         }
    74     }
    75 }

    测试类ThreadPart_2.java

     1 package com.yzl;
     2 
     3 /**
     4  * 传统的线程互斥
     5  * 原理:使用同一个对象(锁)才能实现,
     6  *         静态方法的同步则只能使用类的字节码也就是ClassName.class来做锁
     7  * @author yzl
     8  *
     9  */
    10 public class ThreadPart_2 {
    11     public static void main(String[] args) {
    12         noSyn();
    13         synWithOneObj();
    14         synWithOneStaticObj();
    15     }
    16     
    17     /**
    18      * 未线程同步的
    19      */
    20     private static void noSyn(){
    21         final Work work = new Work();
    22         
    23         Thread thread = new Thread(new Runnable() {
    24             @Override
    25             public void run() {
    26                 while(true){
    27                     work.noSynwrite("wangwu");
    28                 }
    29             }
    30         });
    31         thread.start();
    32         
    33         Thread thread1 = new Thread(new Runnable() {
    34             @Override
    35             public void run() {
    36                 while(true){
    37                     work.noSynwrite("zhangsan");
    38                 }
    39             }
    40         });
    41         thread1.start();
    42     }
    43     
    44     /**
    45      * 使用同一个实例对象做为锁的
    46      */
    47     private static void synWithOneObj(){
    48         final Work work = new Work();
    49         
    50         Thread thread = new Thread(new Runnable() {
    51             @Override
    52             public void run() {
    53                 while(true){
    54                     work.write1("wangwu");
    55                 }
    56             }
    57         });
    58         thread.start();
    59         
    60         Thread thread1 = new Thread(new Runnable() {
    61             @Override
    62             public void run() {
    63                 while(true){
    64                     work.write2("zhangsan");
    65                 }
    66             }
    67         });
    68         thread1.start();
    69     }
    70     
    71     /**
    72      * 使用同一个类的字节码做为锁的
    73      */
    74     private static void synWithOneStaticObj(){
    75         Thread thread = new Thread(new Runnable() {
    76             @Override
    77             public void run() {
    78                 while(true){
    79                     new Work().noSynwrite("wangwu");
    80                 }
    81             }
    82         });
    83         thread.start();
    84         
    85         Thread thread1 = new Thread(new Runnable() {
    86             @Override
    87             public void run() {
    88                 while(true){
    89                     Work.write3("zhangsan");
    90                 }
    91             }
    92         });
    93         thread1.start();
    94     }
    95 }

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

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

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

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

  • 相关阅读:
    python检测服务器端口
    nodejs创建文件
    Git:代码冲突常见解决方法
    爬虫常用库介绍
    关于git提示“warning: LF will be replaced by CRLF”终极解答
    linux系统磁盘使用情况
    tkinter拦截关闭事件
    如何在python中调用C语言代码
    spring in action学习笔记十六:配置数据源的几种方式
    spring in action学习笔记十五:配置DispatcherServlet和ContextLoaderListener的几种方式。
  • 原文地址:https://www.cnblogs.com/yangzhilong/p/4752480.html
Copyright © 2020-2023  润新知