1.进程的三大特征:
独立性:拥有自己的独立的地址空间,一个进程不可以直接去访问其他进程的地址空间。
动态性:是一个系统中活动的指令的集合。
并发性:单个进程可以在多个处理器上并发进行,互不影响。
2.并发性和并行性的区别:
并行是同一个时刻,有多条指令在多个处理器上同时的进行;并发是,快速轮换执行,其实上在宏观上,多个进程同时进行。
3.线程的特点:
一个线程必须有属于自己的一个父进程;线程可以有属于自己的堆栈,程序计数器,局部变量;线程可以和其他的线程共享父进程里的全部的资源;线程不知道是否还有其他的线程存在,线程是抢占的方式进行的。
4.多线程编程:
共享资源;创建线程时为其分配资源的代价小;java内置多线程的支持。
5.线程的创建:
方法一:继承thread类创建进程
Public class firstThread extends Thread
{
Private int i;
Public void run(){
Sop(getName());
}
Public static void main(String[] args){
//创建第一个线程
New firstThread().start();
//创建第二个线程
New firstThread().start();
}
}
特点:多个线程无法共享实例变量。
方法二:实现Runnable接口创建线程类
Public class firstThread extends Thread
{
Private int i;
Public void run(){
Sop(Thread.currentThread.getName());
}
Public static void main(String[] args){
//创建第一个线程
firstThread ft = new firstThread();
New Thread(st,”线程1”).start();
}
}
特点:可以共享线程类的实例变量
原因:程序所创建的只是线程的target,多个线程可以共享一个target,所以可以共享一个线程类的实例变量。
6.线程的生命周期:
新建和就绪:
1)New 时便建立了新的线程,处于新建状态,jvm为其分类了内存,初始化了成员变量的值。
2)启动线程用start 方法,不可以直接调用run方法,否则会将run方法当作是一般的方法来对待处理。
运行和阻塞状态,线程死亡。
7.控制线程:join方法,当调用时,线程将会被阻塞,直到调用join方法的线程执行完毕后,才可以,继续往下执行。
8.后台线程:守护线程,精灵线程,如果所有的前台的线程都死亡了,才会自动死亡。
thread对象的setDaemon()方法,去显示地设置。,但是必须在start方法执行之前去设置。
9.线程睡眠:sleep(),在睡眠时间段内,线程不会获得执行的机会,即使没有可以执行的其他的进程,处于sleep的线程也不会去执行。
Thread.sleep(1000);
睡1000ms
10.线程让步:让当前正在执行的线程暂停,但是不会去阻塞线程,只是将它转入到就就绪的状态,让系统的线程调度器进行重新的调度。当某一个方法执行让步后,只有与它优先级相同或者优先级比他的要高的就绪的线程会得到去执行的机会。
11.线程的同步问题:
目录结构:
实例分析:
package TongBu;
public class Account {
//declare the account number
private String accountNo;
public String getAccountNo() {
return accountNo;
}
public void setAccountNo(String accountNo) {
this.accountNo = accountNo;
}
//declare the money
private double balance;
public double getBalance() {
return balance;
}
public void setBalance(double balance) {
this.balance = balance;
}
//constructor of the accountNo and balance
public Account(String accountNo, double balance) {
super();
this.accountNo = accountNo;
this.balance = balance;
}
//overriding the hashCode method and equals method to make sure it is a same user
public int hashCode(){
return accountNo.hashCode();
}
public boolean equals(Object obj){
if(this==obj){
return true;
}
if(obj!=null&&obj.getClass()==Account.class){
//tranverse the obj to a account target
Account target = (Account)obj;
if(target.getAccountNo()==accountNo){
return true;
}else{
return false;
}
}
return false;
}
}
package TongBu;
public class DrawThread extends Thread{
//user‘s account id
private Account account;
//the money number of user want to draw
private double drawAmount;
//contructor of DrawThread
public DrawThread(String name,Account account,double drawAmount){
super(name);
this.account=account;
this.drawAmount=drawAmount;
}
//the thread main run function
public void run(){
synchronized(account){
//check the remain money is enough
//if the original money can is sufficient
if(account.getBalance()>=drawAmount){
System.out.println("Draw money successfullly!:"+drawAmount);
//update the remain money
account.setBalance(account.getBalance()-drawAmount);
//output the remain money
System.out.println("Remain money is:"+account.getBalance());
}else{
System.out.println("Draw money failed!");
}
}
}
}
package TongBu;
public class DrawTest {
public static void main(String[] args) {
//instance a account object
Account acct = new Account("10001",10000);
//let two thread to draw money from the same account
new DrawThread("shareing",acct,8000).start();
new DrawThread("mm",acct,8000).start();
}
}
方法一:用synchronized(obj){
}
方法二:同步锁:
Class X{
Priavte final ReentrantLock lock = new ReentrantLock();
Public void m(){
//jiasuo
Lock.lock();
Try{
//////
}
Finally{
//jiesuo
Lock.unlock();
}
}
}
12.线程通信:
1)传统方法:Wait() notify() notifyAll()
2)使用condition控制
package TongXin;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Account {
//define a lock object
private final Lock lock = new ReentrantLock();
//get the condition of object
private final Condition cond = lock.newCondition();
// mark to check there is remain money
private boolean flag=false;
//declare the account id
private String accountNo;
public String getAccountNo() {
return accountNo;
}
public void setAccountNo(String accountNo) {
this.accountNo = accountNo;
}
//declare the money
private double balance;
public double getBalance() {
return balance;
}
public void setBalance(double balance) {
this.balance = balance;
}
//constructor of the accountNo and balance
public Account(String accountNo, double balance) {
super();
this.accountNo = accountNo;
this.balance = balance;
}
//overriding the hashCode method and equals method to make sure it is a same user
public int hashCode(){
return accountNo.hashCode();
}
public boolean equals(Object obj){
if(this==obj){
return true;
}
if(obj!=null&&obj.getClass()==Account.class){
//tranverse the obj to a account target
Account target = (Account)obj;
if(target.getAccountNo()==accountNo){
return true;
}else{
return false;
}
}
return false;
}
//the mehod to draw money
public void draw(double drawAmount){
lock.lock();
try{
//no body have deposied money into the account
if(!flag){
cond.await();
}else{
//execute the draw money opreration
System.out.println("Draw money:"+drawAmount);
balance-=drawAmount;
System.out.println("Remain money:"+balance);
//set the flag false means money used up
flag=false;
//notify all thread to deposite money
cond.signalAll();
}
}catch(InterruptedException ex){
ex.printStackTrace();
}
finally{
lock.unlock();
}
}
//the mehod to deposit money
public void deposit(double depositAmount){
lock.lock();
try{
//no body have deposied money into the account
if(flag){
cond.await();
}else{
//execute the draw money opreration
System.out.println("Deposit money:"+depositAmount);
}
balance+=depositAmount;
System.out.println("Remain money:"+balance);
//set the flag false means money used up
flag=true;
//notify all thread to deposite money
cond.signalAll();
}catch(InterruptedException ex){
ex.printStackTrace();
}
finally{
lock.unlock();
}
}
}
package TongXin;
public class DepositThread extends Thread{
private Account account;
private double drawAmount;
public DepositThread(String name,Account account,double drawAmount){
super(name);
this.account=account;
this.drawAmount=drawAmount;
}
public void run(){
for(int i=0;i<5;i++){
account.deposit(drawAmount);
}
}
}
package TongXin;
public class DrawThread extends Thread {
private Account account;
private double drawAmount;
public DrawThread(String name,Account account,double drawAmount){
super(name);
this.account=account;
this.drawAmount=drawAmount;
}
public void run(){
for(int i=0;i<5;i++){
account.draw(drawAmount);
}
}
}
package TongXin;
public class TongXinTest {
public static void main(String[] args){
Account acct = new Account("10101",0);
new DrawThread("draw money",acct,800).start();
new DepositThread("deposit money",acct,800).start();
}
}
3)使用阻塞队列进行控制