zoukankan      html  css  js  c++  java
  • 线程系列2--Java线程的互斥技术

    java的多线程互斥主要通过synchronized关键字实现。一个线程就是一个执行线索,多个线程可理解为多个执行线索。进程有独立的内存空间,而进程中的线程则是共享数据对象资源。这样当多个执行线索在CPU的切换下交替执行,就会出现一些恶心的情况,执行的结果也是匪夷所思。第一个线程未执行完,CPU切换到另一个线程执行,由于数据资源共享,将导致程序的执行混乱。解决线程间的互斥主要就是通过synchronized来实现。

    下面利用传智播客里面的代码举例分析:

    package com.cqfczc.util;
    /**
     * 多线程的互斥技术
     * @author zhenliang
     *
     */
    public class ThreadSynchronized {
    	public static void main(String[] args) {
    		new ThreadSynchronized().testThread();
    	}
    	private void testThread(){
    		final OutPutPrinter printer = new OutPutPrinter();
    		new Thread(new Runnable() {
    			@Override
    			public void run() {
    				while (true) {
    					try {
    						Thread.sleep(20);
    					} catch (InterruptedException e) {
    						e.printStackTrace();
    					}
    					printer.printer("风铃三世爱着猴子");
    				}
    			}
    		}).start();
    		new Thread(new Runnable() {
    			@Override
    			public void run() {
    				while (true) {
    					try {
    						Thread.sleep(20);
    					} catch (InterruptedException e) {
    						e.printStackTrace();
    					}
    					printer.printer("猴子始终喜欢杨婵");
    				}
    			}
    		}).start();
    	}
         //多线程不适用互斥技术时的有问题代码 class OutPutPrinter{ public void printer(String name){ if(name == null){ throw new NullPointerException("参数不能为空!"); } int nameLength = name.length(); for(int i=0;i<nameLength;i++){ System.out.print(name.charAt(i)); } System.out.println(); }
               } }

    1、自定义的对象作为锁对象 
    实现方式 :synchronized(<自定义锁对象>){…} 
    适用情况:当出现需要在多个类(或者多个类的实例)之间进行互斥控制时,需要采用本方法。

    class OutPutPrinter{
    		private String lock = "大泼猴";
    		public void printer(String name){
    			if(name == null){
    				throw new NullPointerException("参数不能为空!");
    			}
    			int nameLength = name.length();
    			synchronized(lock){
    				for(int i=0;i<nameLength;i++){
    					System.out.print(name.charAt(i));
    				}
    				System.out.println();
    			}
    		}
    		
    	}
    

    2、以this作为锁对象 
    实现方式:synchronized(this){…},synchronized实例方法;
    适用情况:适用于使用类的同一个实例(对象)作为锁对象。

            // 同步方法,相当于synchronized(this){}
            public synchronized void output2(String name) {
                int len = name.length();
                for(int i=0; i<len; i++) {
                    System.out.print(name.charAt(i));
                }
                System.out.println();
            }    
    

    3、以Outputer.class作为锁对象 
    Outputer类的字节码对象由jvm自动加载。 
    实现方式:synchronized(Outputer.class){…} ,static synchronized方法 
    适用情况:适用于整个类的所有对象都需要互斥访问的情况

            // 静态同步方法,相当于synchronized(Outputer.class){}
            public static synchronized void output3(String name) {
                int len = name.length();
                for(int i=0; i<len; i++) {
                    System.out.print(name.charAt(i));
                }
                System.out.println();
            }
    

    总结:同一个类中代码块或者方法的互斥,使用this或者类的字节码作为对象锁;当需要在多个类(或者多个类的实例)之间进行互斥控制时,使用自定义对象锁或类字节码对象锁;因为类的字节码全世界只有一份,自定义的对象锁是类内部的一个成员变量,每次创建新对象的时候属性是一样的。

  • 相关阅读:
    20165329 《Java程序设计》第九周学习总结
    20165329 四则运算2
    20165329 第八周补做
    20165329 《Java程序设计》第八周学习总结
    2017-2018-2 学号20165329 实验二《Java面向对象程序设计》实验报告
    20165329 结对编程项目-四则运算
    20165329 第七周学习总结
    20165329 第六周学习总结
    20165329 实验一 java环境的熟悉
    20165329 第五周学习总结
  • 原文地址:https://www.cnblogs.com/aoshicangqiong/p/7679267.html
Copyright © 2011-2022 走看看