前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >知识点——Java中线程安全问题(共享资源冲突问题)和守护线程

知识点——Java中线程安全问题(共享资源冲突问题)和守护线程

作者头像
用户7073689
发布2020-03-17 18:02:05
7430
发布2020-03-17 18:02:05
举报
文章被收录于专栏:青柠小鱼青柠小鱼青柠小鱼
1. 线程安全问题–共享资源能使用问题

例如: <<湄公河行动>> 100张票

淘票票CGV 美团 猫眼 三个销售渠道,100张票是一个共享资源!!! 三个销售渠道,可以认为是三个销售线程!!!

问题一: 100张票共享资源问题,选什么来保存? 局部变量: 在方法内,如果run方法执行,存在,run方法当前执行完毕,销毁。 每一个线程对象中都有run方法,无法满足共享问题 成员变量: 每一个线程对象中,都有一个对应的成员变量,非共享资源。 静态成员变量: 属于类变量,所有的当前类对象,使用的静态成员变量都是一个,而且一处修改,处处 受影响。【共享资源】

问题二: 资源冲突问题

线程之间会相互抢占,而且抢占频率很快,有可能会导致一张票卖了三次,也就是资源冲突问题

在这里插入图片描述
在这里插入图片描述
2. 锁

所以为了解决这个问题,我们用锁来解决

以下锁的是方法,无论谁调用,怎么调用都会锁住

2.1 同步代码块

格式:

synchronized (/* 锁对象 */) { }

特征: 1. synchronized 小括号里面的对象是锁对象,并且要求如果是多线程的情况下,锁对象必须是同一个对象。也就是runnable接口实现类对象。 2. synchronized 大括号中的代码块就是需要进行同步的代码,或者说是加锁的代码,大括号里面的内容,有且只允许一个线程进入。 3. 同步代码块越短越好,在保证安全的情况下,提高性能

问题: 1. 目前锁对象感觉很随意,存在一定的隐患 2. 代码层级关系很复杂,看着有点麻烦 这个方法比较随意,一把锁会锁了多个线程,有隐患

2.2 同步方法

定义在线程类内

synchronized 作为关键字来修饰方法,修饰的方法就是对应的同步方法

有且只允许一个线程进入,到底是谁来完成的加锁操作?

  1. 静态成员方法 锁对象,是当前类对应的字节码文件.class 就是类名.class
  2. 非静态成员方法 锁对象就是当前类对象 this

选择同步方法是否使用static修饰问题

  1. 如果非static修饰,要保证执行的线程对象有且只有一个,因为锁对象就是当前线程对象
  2. 如果是static修饰,锁对象具有唯一性,多个线程使用的锁是同一个锁。类似于同步代码块。
2.3 Lock锁

Java提供了一个对于线程安全问题,加锁操作相对于同步代码块和同步方法更加广泛的一种操作方式。

  1. 对象化操作。 创建Lock构造方法 Lock lock = new ReentrantLock(); 多态思想,不理解就先记着这么用。
  2. 方法化操作。 开锁: unlock(); 加锁: lock();

代码如下:

class SingleThread5 implements Runnable {                                                         
                                                                                                  
	// 共享资源                                                                                       
	private static int ticket = 100;                                                              
	                                                                                              
	// 定义一个成员变量 这里用到了多态的思想,如果不理解,就先记着这么用。                                                                                  
	static Lock lock = new ReentrantLock();                                                       
	                                                                                              
	@Override                                                                                     
	public void run() {                                                                           
		while (true) {                                                                            
                                                                                                  
			// lock对象加锁                                                                           
			lock.lock();                                                                          
			if (ticket > 0) {                                                                     
				System.out.println(Thread.currentThread().getName() + "售出了" + ticket + "张票");     
				ticket -= 1;                                                                      
                                                                                                  
				try {                                                                             
					Thread.sleep(100);                                                            
				} catch (InterruptedException e) {                                                
					// TODO Auto-generated catch block                                            
					e.printStackTrace();                                                          
				}                                                                                 
			} else {                                                                              
				System.out.println(Thread.currentThread().getName() + "售罄!");                     
				break;                                                                            
			}                                                                                     
                                                                                                  
			// 解除锁                                                                                
			lock.unlock();                                                                        
		}                                                                                         
	}                                                                                             
}                                                                                                 
                                                                                                  
public class Demo5 {                                                                              
	public static void main(String[] args) {                                                      
		                                                                                          
		Thread thread1 = new Thread(new SingleThread5(), "淘票票");                                  
		Thread thread2 = new Thread(new SingleThread5(), "猫眼");                                   
		Thread thread3 = new Thread(new SingleThread5(), "美图");                                   
		                                                                                          
		thread1.start();                                                                          
		thread2.start();                                                                          
		thread3.start();                                                                          
	}                                                                                             
}                                                                                                 
2.4 三种加锁方式的总结
  1. 一锁一线程,一锁多线程问题。 使用对应的锁操作对应的线程,考虑静态和非静态问题。 同步方法和Lock锁使用。 静态是一锁多目标,非静态是一锁一目标
  2. 涉及到同步问题时,要考虑好锁对象的选择问题 同步代码块,同步方法,Lock对象。
3. 守护线程

守护线程,也称之为后台线程,如果当前主线程GG思密达,守护线程也就GG思密达。

守护线程一般用于: 1. 自动下载 2. 操作日志 3. 操作监控

方法是通过线程对象 setDeamon(boolean flag); true为守护线程 false缺省属性,正常线程

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 线程安全问题–共享资源能使用问题
  • 2. 锁
    • 2.1 同步代码块
      • 2.2 同步方法
        • 2.3 Lock锁
          • 2.4 三种加锁方式的总结
          • 3. 守护线程
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档