多线程

程序:安装在磁盘上的一段指令集合,它是静态的概念
进程:运行中的程序,是动态的概念,每个进程有独立的资源空间。
线程:又称为轻量级进程,是程序执行的最小单元,是程序中的一个单一的顺序流程,
线程是进程中的一个实体,是被系统独立调度和分派的基本单位。
多线程:指在单个程序中可以同时运行不同的线程,执行不同的任务。

创建线程:
一 1、Java类如继承Thread类,就成为一个线程类,并可通过该类start方法来启动线程,
执行代码。
2、Thread类的子类可以直接实例化,但在子类中必须覆盖run方法才能真正运行线程的代码。
二、通过实现Runnable接口创建线程。
实现Runnable接口的类必须借助Thread类才能创建线程,
eg:1、创建实现Runnable接口的实例
2 、创建一个Thread的对象。将第一个实例化得到的Runnable对象作为参数传到
Thread类的构造方法中。
通过start方法启动线程。

线程的生命周期:
新建 、就绪 、运行、阻塞、 死亡 五种不同的状态可以通过Thread类的方法控制。
1、新建:new操作后,创建了一个线程,该线程仅仅是一个空对象,没有分配资源,
2、就绪:使用start方法后,系统就给线程分配除CPU外的资源,如果某个线程执行了yield方法
则该线程被剥夺了CPU资源,进入就绪状态。
3、运行:占有CPU方法,系统真正执行run()方法。
4、阻塞:因原因不能继续执行时, 原因:对象执行sleep方法等方法时。wait方法时等,
5、死亡: 执行interrupt和stop方法,形成进入死亡状态、。
run方法执行完,则自动死亡。

多线程编程::
线程同步:为了防止多个线程访问一个数据对象时,对数据造成破坏
保证多线程安全访问竞争资源的一种手段。
就是给线程加个限制,让线程执行时别的线程不能执行相应代码。

同步和锁:
Java中每个对象都有一个内置锁。

线程同步一般:把竞争资源设置为private
同步那些访问资源的代码,使用synchronized关键字来修饰方法或代码块,当
synchronized 方法执行完或放生异常时,会自动解锁。、

eg:用synchronized方法设置同步线程。
public class BankDemo{
public static void main(String [] args){
Bank bank= new Bank();
BankThread b1= new BankThread(bank);
b1.start();
BankThread b2= new BankThread(bank);
b2.start();
}
}

class BankThread extends Thread{
private Bank bank =null;

    public BankThread(Bank  bank){
           this.bank =bank;
   }

    public void run(){
          System. out.println("余钱:" +bank .getMoney(400));
   }

}

class Bank{
private int money =500;
//取钱方法:
//当一个线程去调用同步方法时,这个线程就获得了当前对象的锁。
//其他线程调用同步方法时只能等待。
public synchronized int getMoney(int number){
if(number<0){
return -1;
} else if (money <0){
return -2;
} else if (number-money >0){
return -3;
} else{
try {
Thread. sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
money-=number;
System. out.println(“取钱:” +number);
}
return money ;

   }

}

eg:同步代码块 :就是把synchronized方法 包住要执行的代码:

public class BankDemo{
public static void main(String [] args){
Bank bank= new Bank();
BankThread b1= new BankThread(bank);
b1.start();
BankThread b2= new BankThread(bank);
b2.start();
}
}

class BankThread extends Thread{
private Bank bank =null;

    public BankThread(Bank  bank){
           this.bank =bank;
   }

    public void run(){
          System. out.println("余钱:" +bank .getMoney(400));
   }

}

class Bank{
private int money =500;
//取钱方法:
//当一个线程去调用同步方法时,这个线程就获得了当前对象的锁。
//其他线程调用同步方法时只能等待。
public int getMoney(int number){
synchronized (this ) {
if(number<0){
return -1;
} else if (money <0){
return -2;
} else if (number-money >0){
return -3;
} else{
try {
Thread. sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
money-=number;
System. out.println(“取钱:” +number);
}

           }
           return money ;

   }

}

同步产生死锁的原因:
当一个线程已经获得了对象1的锁,同时又想获得对象2的锁,同时有一线程获得对象2的锁
又想获得对象1的锁,这种相互等待对方释放锁的过程,称为死锁。

线程间的通信:
主要方法:wait()
在其他线程调用此对象的 notify() 方法或 notifyAll() 方法前,导致当前线程等待。换句话说,此方法的行为就好像它仅执行 wait(0) 调用一样
notify()

唤醒在此对象监视器上等待的单个线程。

notifyAll()

唤醒在此对象监视器上等待的所有线程。

多线程加锁/释放锁, 经典的消费者/生产者的问题:
eg: 假设仓库中只放一种产品,生产者将产品生产出来放入仓库,消费者将仓库中产品拿出来
如果仓库中没有产品,生产者生产产品,将产品放入仓库,否则停止生产并等待,知道仓库中产
品被消费者取完为止。如果仓库中有产品消费者取走产品,否则停止消费直到仓库中放入产品。
代码:import java.util.LinkedList;

public class ProductorConsumerDemo {

    /**
    * @param args
    */
    public static void main(String[] args) {
           // TODO Auto-generated method stub
            Basket basket= new Basket();
            Productor productor= new Productor(basket);
            Consumer consumer= new Consumer(basket);
            productor.start();
            consumer.start();
   }

}

//消费者类
class Consumer extends Thread{
private Basket basket =null;

    public Consumer(Basket basket) {
           super();
           this.basket = basket;
   }

    //重写run方法 ,实现篮子里取苹果。
    public void run() {
           // TODO Auto-generated method stub
           basket.popApple();
   }

}

//工厂类
class Productor extends Thread{
private Basket basket =null;

    public Productor(Basket basket) {
           super();
           this.basket = basket;
   }

    //重写run方法,实现工厂篮子里放苹果
    public void run() {
           // TODO Auto-generated method stub
           basket.pushApple();
   }

}

class Basket{
private LinkedList basket =new LinkedList();

    //放4轮苹果,
    public synchronized void pushApple(){
           for (int i = 0; i < 20; i++) {
             Apple apple= new Apple(i);
             push(apple);
          }
   }

    //取四轮苹果。
    public synchronized void popApple(){
           for (int i = 0; i < 20; i++) {
                 pop();
          }
   }
    //向篮子里放苹果。
 private void push(Apple apple){
           //当篮子里的苹果为5时,通知消费者取苹果。
           if (basket .size()==5) {
                  try {
                        //苹果到达数量后方苹果等待。
                       wait();
                 } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                       e.printStackTrace();
                 }

                  try {
                       Thread. sleep(500);
                 } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                       e.printStackTrace();
                 }

      }
             basket.addFirst(apple);
                 System. out.println("存放" +apple.toString());
                 notify(); //通知消费者取苹果。
   }

    //篮子里取苹果。
    private void pop(){
           //当篮子里苹果为0时。停止取,并通知生产在者生产。
           if (basket .size()==0) {
                  try {
                        //苹果到达数量后方苹果等待。
                       wait();
                 } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                       e.printStackTrace();
                 }

                  try {
                       Thread. sleep(500);
                 } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                       e.printStackTrace();
                 }


          }
              Apple apple = basket.removeFirst();
                 System. out.println("吃掉" +apple.toString());
                 notify(); //通知生产者来生产。
   }

}

class Apple{
private int id ;
//创建Apple类的构造方法,设置其id.
public Apple(int id){
this.id =id;
}
//重写toString方法。
public String toString() {
return “苹果:” +(id +1);
}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值