栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java基础——线程安全

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java基础——线程安全

线程安全 原因:
因为多个线程同时操作一个数据,会导致数据错乱,所以为了避免这个问题,我们需要对数据操作进行锁定,保证数据的同时只能被一条线程操作
解决方法:锁与同步
锁:
	可以使用任何一个对象作为锁对象
	注意:但是多个线程同时操作一个数据时,要保证锁对象是同一个对象
同步:
	关键字:synchronized
	可以修饰:
    	代码块
    		语法:
    			synchronized(锁对象){
    				//锁对象关闭
    				需要同步的代码
    				//锁对象打开
    			}
    		锁对象:是填入的对象
    	方法:
    		语法:
    			访问权限修饰符 synchronized 返回值类型 方法名(形参列表){
    				//锁对象关闭
    				方法体
    				return 返回值;
    				//锁对象打开
    			}
    		锁对象:谁调用该方法,锁对象就是谁
    	静态方法:
    		语法:
    			访问权限修饰符 synchronized static 返回值类型 方法名(形参列表){
    				//锁对象关闭
    				方法体
    				return 返回值;
    				//锁对象打开
    			}
    		锁对象:该方法所属的类的类对象,一个类只有一个对象
举例说明
举例1:
	1、有一张银行卡里面有50000块钱
	2、银行还给了一个存折
	3、拿着银行卡去取钱
	4、拿着存折去取钱
举例2:
	有一辆火车,从西安开往北京,有200张票,同时交给四个窗口售票
当多个线程同时操作一个数据时会引起数据安全的问题
解决线程安全问题
思路:因为是多个线程同时操作一个数据,会导致数据安全问题,所以只要保证数据同时只能被一条线程操作,就可以解决该问题

所以我们使用锁来解决该问题,但是要保证锁对象是同一个

关键字:synchronizde

可以修饰:
	1、代码块
		synchronizde(锁对象){
			//关闭锁
			要同步的代码
			//开启锁
		}
		同步代码:同时只能被一条线程执行的代码,称为同步代码,反之,同时可以被多个线程操作的代码称为异步代码
		锁对象:任何一个类的对象都可以做为锁对象
	2、普通方法
		语法:
			访问权限修饰符 synchronized 返回值类型 方法名(形参列表){
				//锁对象关闭
    			方法体
    			return 返回值;
    			//锁对象打开
			}
		锁对象:谁调用这个方法,锁对象就是谁
	3、静态方法
		语法:
			访问权限修饰符 synchronized static 返回值类型 方法名(形参列表){
				//锁对象关闭
    			方法体
    			return 返回值;
    			//锁对象打开
			}
		锁对象:该方法所属的类的类对象,一个类只有一个对象
练习:用代码证明synchronized修饰普通方法与静态方法的锁对象是谁?
package com.qianfen.Test;
//用代码证明synchronized修饰普通方法与静态方法的锁对象是谁?
public class Test01 {
	public static void main(String[] args) {
		A a = new A();
		Class class1 = a.getClass();
		
		Thread thread = new Thread(new Runnable() {
			
			@Override
			public void run() {
				// TODO Auto-generated method stub
				A.aTest();
			}
		});
		thread.start();
		
		synchronized (A.class) {
			System.out.println("进入主线程main方法");
			try {
				Thread.sleep(10000);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			System.out.println("即将结束主线程main方法");
		}
	}
}
class A{
	public synchronized static void aTest() {
		System.out.println("进入aTest方法中");
		try {
			Thread.sleep(10000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		System.out.println("即将结束aTest方法");
	}
}
线程间通讯
以下的方法是Object类提供的
等待:
	wait();				在那个线程调用该方法,就是让该线程无限期等待,会释放锁对象
	wait(long timeout)	在那个线程调用该方法,就是让该线程有限期等待,会释放锁对象
通知:
	noyify()			使用那个对象调用该方法,就随机唤醒一条以该对象作为锁的线程
	notifyAll()			使用那个对象调用该方法,就唤醒所有以该对象作为锁的线程
	
注意:
	1、只能在同步代码中使用,并且该同步代码的锁对象就是调用以上方法的对象,不然不会出现IllegalMonitorStateException异常
	2、以上方法是Object提供的
Thread:是线程类
创建一个Thread类的对象作用是什么?
	一条新的执行路径,这条路径中执行的代码都在run方法中
作用:使项目同时可以执行多个任务
死锁
原因:
	线程1执行A任务
		sy....(a1){
			xxxx 		//a1锁了
			xxxx
			sy...(b1){
				xxx
				xxx
			}
		}
	线程2执行B任务
		sy....(b1){
			xxx 		//b1锁了
			xxxx
			sy....(a1){
				xxxx
				xxxx
			}
		}
原理:多个线程互相持有对方所需的锁对象,导致这几个线程无法正常运行所以在写代码时要尽量避免死锁
注意:尽量不要再同步中使用同步

作业:使用四个线程,编写一个死锁,使四个线程都无法正常结束
生产者与消费者模式
生产者线程
	无限执行生产任务
消费者线程
	无限执行消费任务
工厂
	库存数量
	最大库存数量
	生产的方法:同步
	消费的方法:同步
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/827387.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号