zoukankan      html  css  js  c++  java
  • 传统的同步线程锁(两)

    一. 线程安全

    线程安全问题是指程序中公用的东西被多个线程訪问,比方:类的静态变量

    线程互斥:是指两个线程之间不能够同一时候执行,他们会互斥,必须等待一个线程执行完成,还有一个才干执行


    二. 同步锁

    有什么办法能够解决线程安全问题呢?那就是在程序中加锁

    Java有两种加锁的方法:

    1. 在代码块中加锁 synchronized (this) { ... }

    2. 在方法上加锁 public synchronized void xxx(){ ... }


    演示样例代码:

    public class TraditionalThreadSynchronized {
    
    	public static void main(String[] args) {
    		new TraditionalThreadSynchronized().init();
    	}
    
    	private void init() {
    		final Outputer outputer = new Outputer();
    
    		// 线程1
    		new Thread(new Runnable() {
    			@Override
    			public void run() {
    				while (true) {
    					try {
    						Thread.sleep(10);
    						outputer.output1("1111111111");
    					} catch (Exception e) {
    						e.printStackTrace();
    					}
    				}
    			}
    		}).start();
    
    		// 线程2
    		new Thread(new Runnable() {
    			@Override
    			public void run() {
    				while (true) {
    					try {
    						Thread.sleep(10);
    						outputer.output1("2222222222");
    					} catch (Exception e) {
    						e.printStackTrace();
    					}
    				}
    			}
    		}).start();
    	}
    
    	class Outputer {
    		public void output1(String name) {
    			// 同步代码块
    			synchronized (this) {
    				for (int i = 0; i < name.length(); i++) {
    					System.out.print(name.charAt(i));
    				}
    				System.out.println();
    			}
    		}
    		
    		// 同步方法
    		public synchronized void output2(String name) {
    			for (int i = 0; i < name.length(); i++) {
    				System.out.print(name.charAt(i));
    			}
    			System.out.println();
    		}
    	}
    
    }

    线程1和线程2由于都要调用output1方法并打印传入的name字符串。cpu就会来回的在两个线程之间切换,

    有可能线程1打印到一半的时候就切换到线程2上。这显然是我们不想看到的,所以在代码内容中加锁,

    这样能够保证一个线程调用方法结束才会运行下一个线程。


    上面代码中的this指的是outputer对象,它就是一把锁,两个线程使用同一把锁才干实现同步。


    而在方法上加锁也能够实现线程同步,在方法上使用synchronizedkeyword也是把this作为锁。

    事实上output1方法和output2方法也是同步的,由于他们都是使用this作为锁。


    思考一个问题:假设把一个方法定义为静态的即:public static synchronized

    那么它使用什么作为锁呢?答案是:该类的字节码对象xxx.class


    三. Synchonized和ThreadLocal

    ThreadLocal和Synchonized都用于解决多线程并发訪问,可是它们之间有本质差别,synchonized是利用锁机制,使变量或代码块在某一时刻仅仅能被一个线程訪问,而ThreadLocal为每个线程提供一个变量副本,每个线程在同一时间訪问到的并非同一个对象,这样就隔离了多个线程对数据的共享,而Synchronized却正好相反。它用于在多个线程间通信时可以获得数据共享。

    总结:synchonized用于线程间数据共享。ThreadLocal用于线程间数据隔离。



    版权声明:本文博主原创文章,博客,未经同意不得转载。

  • 相关阅读:
    swift函数
    Swift数据类型
    swift的特点
    图片适配、九宫切图
    iOS中视图控制器的生命周期
    CocoaPods的安装与使用
    SQLite3的使用
    Pickers应用程序
    多视图应用
    OC对象的三大特性:封装、继承和 多态
  • 原文地址:https://www.cnblogs.com/bhlsheji/p/4887957.html
Copyright © 2011-2022 走看看