传统的同步线程锁(两)

一. 线程安全

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

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

二. 同步锁

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

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用于线程间数据隔离。

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

时间: 2024-10-29 19:05:34

传统的同步线程锁(两)的相关文章

Java同步—线程锁和条件对象

线程锁和条件对象 在大多数多线程应用中,都是两个及以上线程需要共享对同一数据的存取,所以有可能出现两个线程同时访问同一个资源的情况,这种情况叫做:竞争条件. 在Java中为了解决并发的数据访问问题,一般使用锁这个概念来解决. 有几种机制防止代码收到并发访问的干扰: 1.synchronized关键字(自动创建一个锁及相关的条件) 2.ReentrantLock类+Java.util.concurrent包中的lock接口(在Java5.0的时候引入) ReentrantLock的使用 publi

【java并发】传统线程技术中创建线程的两种方式

传统的线程技术中有两种创建线程的方式:一是继承Thread类,并重写run()方法:二是实现Runnable接口,覆盖接口中的run()方法,并把Runnable接口的实现扔给Thread.这两种方式大部分人可能都知道,但是为什么这样玩就可以呢?下面我们来详细分析一下这两种方法的来龙去脉. 1. 揭秘Thread中run()方法 上面我们看到这两种方式都跟run()方法有关,所以我们来看一下Thread的源码中run()方法到底都干了什么: @Override public void run()

Java线程:线程的同步与锁

一.同步问题提出 线程的同步是为了防止多个线程访问一个数据对象时,对数据造成的破坏. 例如:两个线程ThreadA.ThreadB都操作同一个对象Foo对象,并修改Foo对象上的数据. public class Foo {     private int x = 100; public int getX() {         return x;     } public int fix(int y) {         x = x - y;         return x;     } }

Java线程:线程的同步与锁

1.同步和锁 java中每个对象都有一个内置锁,程序执行非静态的synchronized同步方法时,自动获得执行该方法的对象有关的锁. 一个对象只有一个锁,当一个线程获得锁,其他线程不能进入该对象上的synchronized方法或代码块.直到锁被释放. 线程可以有多个锁,例如,一个对象的同步方法中调用另一个对象的同步方法 2.静态方法的同步 同步静态方法,用的是类对象的锁,即xx.class. 3.线程安全类 对类中的方法进行了同步,但操作这个类时仍然不一定安全. 例如: public  cla

Objective-C中的同步线程的锁

概述 在多线程编程中往往会遇到多个线程同时访问共享的资源,这种情况我们需要通过同步线程来避免.也就是给线程加锁. 因为Objective-C是C语言的超集.,严格的来说是真超集.所以C语言当中的pthread互斥锁在Objective-C中也可以使用,但是Objective-C中定义了本身自己的锁对象和锁协议,所以本篇介绍Objective-C中的锁. NSLock NSLocking协议 @protocol NSLocking - (void)lock; - (void)unlock; @en

python笔记10-多线程之线程同步(锁lock)

前言 关于吃火锅的场景,小伙伴并不陌生,吃火锅的时候a同学往锅里下鱼丸,b同学同时去吃掉鱼丸,有可能会导致吃到生的鱼丸.为了避免这种情况,在下鱼丸的过程中,先锁定操作,让吃火锅的小伙伴停一会,等鱼丸熟了再开吃,那么python如何模拟这种场景呢? 未锁定 1.如果多个线程同时操作某个数据,会出现不可预料的结果.比如以下场景:当小伙伴a在往火锅里面添加鱼丸的时候,小伙伴b在同时吃掉鱼丸,这很有可能导致刚下锅的鱼丸被夹出来了(没有熟),或者还没下锅,就去夹鱼丸(夹不到). # coding=utf-

Java04 线程同步问题解决——线程锁(同步锁、互斥锁)

目录 [TOC] 写在最前: 可能有误,请大家批评指正 一.线程切换 Java中,如果要实现在一个线程间的线程切换,需要在线程中使用Thread.yield()即可让出CPU时间. 二.线程锁(也叫同步锁.互斥锁) 线程锁可以在有效缩小同步范围的同时,尽可能的保证并发效率 2.1 使用synchronized关键字对方法进行加锁 对整个线程处理加锁(严重影响效率,不常用) 2.1.1 语法 public synchronized void test(){ } 2.1.2 案例 package c

002-多线程-锁-同步锁-synchronized几种加锁方式、Java对象头和Monitor、Mutex Lock、JDK1.6对synchronized锁的优化实现

一.synchronized概述基本使用 为确保共享变量不会出现并发问题,通常会对修改共享变量的代码块用synchronized加锁,确保同一时刻只有一个线程在修改共享变量,从而避免并发问题. synchronized结论: 1.java5.0之前,协调线程间对共享对象的访问的机制只有synchronized和volatile,但是内置锁在功能上存在一些局限性,jdk5增加了Lock以及ReentrantLock. 2.java5.0,增加了一种新的机制:显式锁ReentrantLock,注意它

线程同步与锁

二元信号量,多元信号量,互斥量,临界区.其它包括读写锁,条件变量. -1:二元信号量,适合与只能被一个线程独占访问的资源.当二元信号量处于非占用状态时,第一个试图获取该二元信号量的线程会获得该锁,并将二元信号量重置为占用状态,在未释放该锁前,其它所有试图获取该二元信号量的线程将会等待. -2:多元信号量,简称信号量.一个初始值为N的信号量允许N个线程并发访问. 获取该信号量时,信号量的值减一,当信号量的值小于0时,再来获取信号量的线程进入等待状态. 释放该信号量时,信号量的值加一,当信号量的值大