Java多线程
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java多线程相关的知识,希望对你有一定的参考价值。
11.1)多线程概念
11.2)创建多线程的2种方法
11.3)多线程的生命周期
11.4)同步(掌握)
为什么需要同步?
因为线程安全问题,举例—银行取钱问题,多线程对同一个银行账户进行取钱任务,账户会出现负值的资产,不符合现实生活
所以,当多个线程访问同一资源时,很容易“偶然”出现安全问题
什么是同步
避免出现安全问题的方法就是同步
2种实现同步的方法
第一种是 synchronized代码块
synchronized{ //需要保护的代码 ... }
第二种是 同步方法(用synchronized关键字修饰)
public synchronized void func(){ .... }
ThreadLocal类
ThreadLocal 线程局部变量,支持泛型,通过使用线程局部变量也可以避免多线程访问同一资源时出现“安全问题”,其方式是通过复制多份同一资源的副本供多线程使用,也就是说每一个线程访问时,都拥有一个副本变量
ThreadLocal 只提供三个三个public方法:
T get():返回此线程局部变量中当前线程副本中的值 void remove():删除此线程局部变量中当前线程副本中的值 void set(T value):设置此线程局部变量中当前线程副本中的值
使用如下:
1. class Account{ 2. /** 3. * 定义一个ThreadLocal类型的变量,该变量将是一个线程局部变量 4. * 每个线程都会保留该变量的一个副本 5. */ 6. private ThreadLocal<String> name = new ThreadLocal<>(); 7. //定义一个初始化name成员变量的构造器 8. public Account(String name){ 9. this.name.set(name); 10. //下面代码用于访问当前线程的name副本的值 11. System.out.println("-----"+this.name.get()); 12. } 13. //name的getter、setter方法 14. public String getName(){ 15. return this.name.get(); 16. } 17. public void setName(String name){ 18. this.name.set(name); 19. } 20. } 21. class MyThread extends Thread{ 22. //定义一个Account类型的成员变量 23. private Account account ; 24. public MyThread(Account acct,String name){ 25. super(name); 26. this.account = acct; 27. } 28. 29. public void run(){ 30. 31. for(int i = 0;i<10;i++){ 32. //当i==6时,输出将账户名代替为当前线程名 33. if(i==6){ 34. account.setName(getName()); 35. } 36. //输出同一个账户的账户名与循环变量 37. System.out.println(account.getName()+"账户i的值:"+i); 38. } 39. } 40. } 41. public class ThreadLocalTest{ 42. public static void main(String[] args){ 43. //启动两个线程,共享同一个Account 44. Account acct = new Account("初始名"); 45. /** 46. * 虽然两个线程共享同一个账户,即只有一个账户名 47. * 但由于账户名是ThreadLocal类,所以每个线程 48. * 都完全拥有各自的账户名副本,因此在i==6之后,将看到 49. * 两个线程访问同一账户时出现不同的账户名 50. */ 51. new MyThread(acct,"线程甲").start(); 52. new MyThread(acct,"线程乙").start(); 53. } 54. }
以上是关于Java多线程的主要内容,如果未能解决你的问题,请参考以下文章