Java死锁和线程范围内共享数据
2018-04-10 15:01
399 查看
一般来说:出现死锁问题要满足以下条件
互斥条件:一个资源每次只能被一个线程访问
请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放
不剥夺条件:进程已获得的资源,在未使用完之前,不能剥夺。
循环等待条件:若干进程之间形成一种头尾相接的循环等待状态
只要破坏其中任意一个,死锁的问题就能被解决
二:线程范围内共享数据
所谓线程范围内共享数据,即对于相同的程序代码,多个模块在统一线程运行中要共享一份数据,Api为我们提供了一个线程范围内共享数据的类ThreadLocal
使用map实现线程范围内数据的共享
原理:将线程对象作为map的键存入,这样就保证了map对象的唯一,也就保证了数据的唯一。
ThreadLocal类
1)该示例包含了对基本数据类型的共享和对象数据类型的共享
2)定义一个全局共享的ThreadLocal变量,然后启动多个线程向该ThreadLocal变量随机存储一个值,接着,各个线程调用其他类的方法读取ThreadLocal变量的值,就可以看到多个类在同一线程共享同一份数据。
3)每次存储数据时,用的都是同一个ThreadLocal变量,只是重新赋值而已
互斥条件:一个资源每次只能被一个线程访问
请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放
不剥夺条件:进程已获得的资源,在未使用完之前,不能剥夺。
循环等待条件:若干进程之间形成一种头尾相接的循环等待状态
只要破坏其中任意一个,死锁的问题就能被解决
二:线程范围内共享数据
所谓线程范围内共享数据,即对于相同的程序代码,多个模块在统一线程运行中要共享一份数据,Api为我们提供了一个线程范围内共享数据的类ThreadLocal
使用map实现线程范围内数据的共享
原理:将线程对象作为map的键存入,这样就保证了map对象的唯一,也就保证了数据的唯一。
package com.java.day8; import java.util.HashMap; import java.util.Map; import java.util.Random; /** * Created by wangkaishuang on 18-4-10 */ public class ThreadScopeShareData { private static int data = 0; private static Map<Thread,Integer> threadData = new HashMap<>(); public static void main(String[] args) { for (int i = 0; i < 2; i++) { new Thread(new Runnable() { @Override public void run() { int data = new Random().nextInt(); threadData.put(Thread.currentThread(), data); System.out.println(Thread.currentThread() + "has input data" + data); new A().get(); new B().get(); } }).start(); } } static class A { public void get() { int data = threadData.get(Thread.currentThread()); System.out.println("A from " + Thread.currentThread().getName() + " get data :" + data); } } static class B{ public void get(){ int data = threadData.get(Thread.currentThread()); System.out.println("B from " + Thread.currentThread().getName() + " get data :" + data); } } }
ThreadLocal类
1)该示例包含了对基本数据类型的共享和对象数据类型的共享
2)定义一个全局共享的ThreadLocal变量,然后启动多个线程向该ThreadLocal变量随机存储一个值,接着,各个线程调用其他类的方法读取ThreadLocal变量的值,就可以看到多个类在同一线程共享同一份数据。
3)每次存储数据时,用的都是同一个ThreadLocal变量,只是重新赋值而已
package com.java.day8; import java.util.HashMap; import java.util.Map; import java.util.Random; public class ThreadLocalDemo { private static ThreadLocal<Integer> x = new ThreadLocal<Integer>(); //创建一个存储封装类对象的ThreadLocal private static ThreadLocal<MyThreadScopeData> myThreadScopeData = new ThreadLocal<MyThreadScopeData>(); private static int data = 0; public static void main(String[] args){ //产生两个线程 for(int i=0;i<2;i++){ new Thread(new Runnable(){ @Override public void run() { //共享单一的数据 int data = new Random().nextInt(); System.out.println(Thread.currentThread().getName()+"has put data : "+data); x.set(data); //共享多个数据 //将数据封装在myData对象中,并将myData作为myThreadScopeData的键 MyThreadScopeData myData = new MyThreadScopeData(); myData.setName("name "+data); myData.setAge(data); myThreadScopeData.set(myData); new A().get(); new B().get(); } }).start(); } } static class A{ public void get(){ int data = x.get(); System.out.println("A from "+Thread.currentThread().getName()+" get data :"+data); //从myData中取出数据,并获取当前线程名,数据 MyThreadScopeData myData = myThreadScopeData.get(); System.out.println("A from "+Thread.currentThread().getName()+" getMyData: " + myData.getName() + "," +myData.getAge()); } } static class B{ public void get(){ int data = x.get(); System.out.println("B from "+Thread.currentThread().getName()+" get data :"+data); MyThreadScopeData myData = myThreadScopeData.get(); System.out.println("B from "+Thread.currentThread().getName()+" getMyData: " + myData.getName() + "," +myData.getAge()); } } } //封装数据的类 class MyThreadScopeData{ private String name; private int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }
相关文章推荐
- Java中如何实现单个线程范围内的数据共享
- 【java并发】线程范围内共享数据
- ThreadLocal实现:java线程范围内的共享数据,线程外独立
- java 多线程 day05 线程范围内的数据共享
- Java基础:多线程之线程范围内的数据共享ThreadLocal
- java高级之线程范围内的共享数据
- JAVA笔记14__多线程共享数据(同步)/ 线程死锁 / 生产者与消费者应用案例 / 线程池
- Java基础——ThreadLocal实现线程范围内的数据共享
- java多线程学习(三)---线程范围内数据共享
- Java笔记1 : 在生产者消费者模式中,线程通信与共享数据,死锁问题与解决办法
- 黑马程序员--读写字节数组,随机读写流,集合IO的思维导图,多线程部分,单例设计模式,线程和进程的概念,Java中的线程的创建方式,线程的随机性,线程的状态图,多线程操作共享数据的安全性,死锁
- Java并发05---线程范围内的共享数据
- Java并发库(五、六、七):线程范围内共享数据、ThreadLocal、共享数据的三种方法
- java多线程与线程并发四:线程范围内的共享数据
- java多线程:5、线程范围内的数据共享_ThreadLocal
- Java基础加强 线程范围内数据共享设计模式
- java线程范围内的数据共享
- Java线程与并发库高级应用-线程范围内共享数据ThreadLocal类
- 黑马程序员---java中如何实现线程范围内共享数据
- Java线程范围内的共享数据(2)