java多线程之述解

提及线程 就不得不提进程 他们之间的关系很紧密 java

进程:内存中运行的应用程序 每一个进程都有本身的一块内存空间 而线程是进程中的一个执行单元 一个进程中能够有多个线程 多线程的好处就是能够并发操做程序 将cpu资源利用率最大化 就像咱们生活中同样 当咱们在一个视屏网站下电影的时候 咱们能够去作一些其余的时间 不须要一直等着电影下完再去作不会耗费多余的时间 这就是多线程的好处安全

如何实现多线程呢多线程

1.继承Thread类 而后重写run方法并发

2.实现Runnable接口实现重写·ide

 
特色
继承thread类
只适用于单继承 编写简单 能够直接操做
实现runnable接口
能够实现多继承

 

 

 

 

线程的状态测试

1.新建状态网站

线程在被建立后就进入了新建状态 例如Thread thread=newThread();this

2.就绪状态(也称为可执行转态)spa

线程再被建立后 若是调用了 start();说明该线程随时准备执行
3.运行状态
这时线程已经拿到了cpu执行权限 须要注意的是 线程可能没有被执行完 就被抢了 这时他又会回到就绪状态
4.阻塞状态
由于线程放弃了cpu的使用权 暂时中止执行操做 直到线程进入到就绪状态才有机会转到运行状态
阻塞状况分为三种:
       1.等待阻塞:经过调用线程的wait方法 等待线程的执行 (例如 你去银行取钱的时候 忘记带银行卡啦 因此你打电话给你老婆让他送卡过来 在这段时间里面你就一直在等待他))
       2.其余阻塞:经过调用线程的sleep()或join()或发出了I/O请求时,线程会进入到阻塞状态 (例如 去银行取钱的时候感受有点困 睡着了 别人也进不来)
        3.同步阻塞:
线程在获取 synchronized同步锁失败(由于锁被其余线程锁占用)他会进入到同步阻塞状态 也称只为死锁() (例如 你去银行取钱一直在排队等 可是别人在银行atm里面就一直不出来 可是你不死心 仍是一直在等)
5.死亡状态
线程执行完退出exit或者因异常退出
 
线程调度
 join() 插队 让当前线程执行完了以后在执行其余线程
join( long millis); 让出时间让你先执行 时间到了之后再继续抢
yield(); 暂停此次执行机会 再来竞争(至关于让你一次)
sleep() 让此线程休眠多长时间
notify()   唤醒在此对象监视器上等待的单个线程。
notifyAll()  唤醒在此对象监视器上等待的全部线程。
wait()    让当前线程处于“等待(阻塞)状态”,“直到其余线程调用此对象的 notify() 方法或 notifyAll() 方法”,当前线程被唤醒(进入“就绪状态”)。
 
java线程安全
当多个线程去操做同一对象的同一个属性时,执行的结果可能与预期不符。这时 这个对象就称为线程不安全的对象  这个对象所在的类成为线程不安全类
这时咱们有两种方法能够解决
1.同步方法 
只须要在方法上添加一个synchronized修饰符便可 
       这种方法很是简单 可是效率很低 由于他把全部的操做都上锁了(例如去银行取钱应该是一个完整的操做 咱们只须要将取卡 插卡 取钱 拿卡这几部上锁就够了 由于咱们取钱的时候卡已经拿出来了放在手上 若是等到我了 我直接就能够去插卡了 很快 可是若是我取卡的步骤放到atm机里面去 找了很半天才找到卡是否是很浪费时间 若是每一个人都是这样时间更长 因此说我在外面将卡找好了就能够节省时间)
2.同步代码块
须要将那些一块儿执行的代玛写在代码块中
synchronized(这里是一个锁对象 这个锁对象必须是一个不会改变的对象){
                   这里写的是那些须要一块儿执行的代码块
}
 
接下来举例说明
去银行取钱若是使用单线程会发生什么?
 1 package com.newroad.thread.test;  2 //帐户类
 3 public class Account {  4     private double balance;  5     private Object lock=new Object();  6     public Account(double balance) {  7         super();  8         this.balance = balance;  9  } 10     public  void withdrawMoney(double money) { 11     String name=Thread.currentThread().getName(); 12     System.out.println(name+"取款前帐户余额为:"+balance); 13         if (balance>=money) { 14             balance=balance-money; 15             System.out.println(name+"取款金额为:"+money +"取款后,余额为:"+balance); 16         }else { 17             System.out.println(name+"余额不足,帐户余额为:"+balance+"取款金额为;"+money); 18  } 19         
20  } 21 
3
34 
35 } 36 
37 //线程类
38 package com.newroad.thread.test;
40 public class PersonThread extends Thread { 41     private Account account; 42     private double drawbalance; 43     public PersonThread(Account account, double drawbalance) { 44         super(); 45         this.account = account; 46         this.drawbalance = drawbalance; 47  } 48 
49  @Override 50     public void run() { 51  account.withdrawMoney(drawbalance); 52 
53  } 54 
55 } 56 
57 
58 //这是测试类
59 package com.newroad.thread.test; 60 
61 public class Test { 62 public static void main(String[] args) { 63     Account account=new Account(4000); 64     PersonThread p=new PersonThread(account, 2400); 65     PersonThread p1=new PersonThread(account, 1000); 66     PersonThread p2=new PersonThread(account, 600); 67     p.setName("张三"); 68     p1.setName("张三媳妇"); 69     p2.setName("张三爸"); 70  p.start(); 71  p1.start(); 72  p2.start(); 73  } 74 }

 

 这是运行后的结果 明显不对 咱们能够明显发现 只有张三的操做是没有问题的 他媳妇和他爸都是有问题的 这确定是有问题的 这时就可使用加锁的方法 让一个线程执行完了在让其余线程在执行 而生活中 咱们去银行ATM机上取钱都会有一个门 等我全部操做都完了其余人才能进来 这就至关于咱们程序中的锁
这时咱们只须要修改 帐户类就能够啦
 1 package com.newroad.thread.test;  2  3 public class Account {  4 private double balance;  5 private Object lock = new Object();  6  7 public Account(double balance) {  8 super();  9 this.balance = balance; 10  } 11 public void withdrawMoney(double money) { 12 String name = Thread.currentThread().getName(); 13 synchronized (this) { 14 System.out.println(name + "取款前帐户余额为:" + balance); 15 if (this.balance >= money) { 16 balance = balance - money; 17 System.out.println(name + "取款金额为:" + money + "取款后,余额为:" + balance); 18 } else { 19 System.out.println(name + "余额不足,帐户余额为:" + balance + "取款金额为;" + money); 20  } 21  } 22  } 23 24 }

这时咱们就能够发现就没问题了线程

相关文章
相关标签/搜索