java多线程学习二

java多线程学习2
一、线程的基本概念
简单的说:线程就是一个程序里不同的执行路径
在同一个时间点上cpu只会有一个线程在执行
Java里的多线程是通过java.lang.Thread类来实现的
每个线程都拥有自己独立的方法栈空间

二、java线程的创建和启动
第一种
定义线程类实现Runnable接口
Thread myThread = new Thread(target) //target为Runnable接口类型
Runnable中只有一个方法:
public void run();用以定义线程运行体
第二种
可以定义一个Thread的子类并重写其run方法:
  clas MyThread extends Thread{
   public void run(){}
  }
线程类必须通过执行Thread的start()方法启动一个新的线程
如果调用run()方法是属于方法的调用,不会启动一个新的线程
推荐使用第一种方式创建线程,使用接口较为灵活

二、线程状态装换
调用线程start()方法时,线程进入就绪状态,Cpu分配时间片,线程进入运行状态
时间片结束,run()方法未执行完,线程进入阻塞状态。

三、线程控制基本方法
isAlive() //判断线程是否还“活着”,即线程是否还未终止
getPriority() //获得线程的优先级数值
setPriority() //设置线程的优先级指数
Thread.sleep() //静态方法,将当前线程睡眠指定毫秒数
join()  //调用某线程的该方法,将当前线程与该线程合并,
   //即等待该线程结束,再回复当前线程的运行。
yield()  //让出CPU,当前线程进入就绪状态等待调度
interrupt() //中断线程
wait()  //当前线程进入对象的wait pool
notify()/all //唤醒对象的wait pool中的一个/所有等待线程

四、sleep方法
Thread的静态方法
public static void sleep(long millis)throws InterruptedException
必须对异常进行捕捉
Thread.currentThread();  //拿到当前线程

五、interrupt方法一种让线程退出的方式。


import java.util.*;
public class TestInterrupt{
    public static void main(String[] args){
        MyThread t = new MyThread();
        t.start();
        try{Thread.sleep(10000);}
        catch(InterruptedException i){}
        t.interrupt();
    }
}

class MyThread extends Thread{
    public void run(){
        while(true){
            try{
                System.out.println("------"+new Date()+"-----");
                Thread.sleep(1000);
            }catch(InterruptedException i){
                return;
            }
        }
    }
}



六、join和yield方法
t.join(); //t的run()方法完才会继续执行当前线程方法体
   //也就是两个线程变成了一个线程
t.yield(); //暂停当前正在执行的线程对象,并执行其他线程。方法为静态
   //哪个线程体执行此方法,哪个线程让步


public class TestYield {
  public static void main(String[] args) {
    MyThread3 t1 = new MyThread3("t1");
    MyThread3 t2 = new MyThread3("t2");
    t1.start(); t2.start();
  }
}
class MyThread3 extends Thread {
  MyThread3(String s){super(s);}
  public void run(){
    for(int i =1;i<=100;i++){
      System.out.println(getName()+": "+i);
      if(i%10==0){
        yield();
      }
    }
  }
}




七、线程优先级别
线程的优先级用数字表示,范围从1到10,一个线程的缺省优先级为5.
Thread.MAX_PRIORITY=1
Thread.MIN_PRIORITY=10
Thread.NORM_PRIORITY=5
例:t.setPriority(Thread.NORM_PRIORITY+3);

★八、线程同步
1.同步代码块
synchronized(this){  //在执行代码块过程中,不会被其他线程打断
  ... 
}
public sunchronized void method //执行此方法时,当前对象被锁定
在Java语言中,引入了对象互斥锁的概念,保证共享数据操作的完整性,每个对象 都对应一个可称为"互斥锁"的标记,这个标记保证在任一时刻,只能有一个线程访 问该对象。
2.线程死锁


public class TestDeadLock implements Runnable {
    public int flag = 1;
    static Object o1 = new Object(), o2 = new Object();
    public void run() {
System.out.println("flag=" + flag);
        if(flag == 1) {
            synchronized(o1) {
                try {
                    Thread.sleep(500);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                synchronized(o2) {
                    System.out.println("1");   
                }
            }
        }
        if(flag == 0) {
            synchronized(o2) {
                try {
                    Thread.sleep(500);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                synchronized(o1) {
                    System.out.println("0");
                }
            }
        }
    }   
   
    public static void main(String[] args) {
        TestDeadLock td1 = new TestDeadLock();
        TestDeadLock td2 = new TestDeadLock();
        td1.flag = 1;
        td2.flag = 0;
        Thread t1 = new Thread(td1);
        Thread t2 = new Thread(td2);
        t1.start();
        t2.start();
       
    }
}



九、生产者消费者问题


public class ProducerConsumer {
    public static void main(String[] args) {
        SyncStack ss = new SyncStack();
        Producer p = new Producer(ss);
        Consumer c = new Consumer(ss);
        new Thread(p).start();
        new Thread(p).start();
        new Thread(p).start();
        new Thread(c).start();
    }
}

class WoTou {
    int id;
    WoTou(int id) {
        this.id = id;
    }
    public String toString() {
        return "WoTou : " + id;
    }
}

class SyncStack {        //栈实现
    int index = 0;
    WoTou[] arrWT = new WoTou[6];    //相当于装物品的篮子
   
    public synchronized void push(WoTou wt) {    //生产物品,线程安全
        while(index == arrWT.length) {        //当篮子满了线程等待
            try {           
                this.wait();       
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
           
        }
        this.notifyAll();    //开始生产时,叫醒等待的其他线程开始消费
        arrWT[index] = wt;   
        index ++;
    }
   
    public synchronized WoTou pop() {        //消费物品,线程安全
        while(index == 0) {            //如果篮子空了
            try {
                this.wait();        //线程等待,等待生产者开始                            //生产,叫醒此线程
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
           
        }
        this.notifyAll();            //消费时喊醒生产者生产
        index--;
        return arrWT[index];
    }
}

class Producer implements Runnable {            //生产者类
    SyncStack ss = null;
    Producer(SyncStack ss) {
        this.ss = ss;
    }
   
    public void run() {
        for(int i=0; i<20; i++) {    //生产20个
            WoTou wt = new WoTou(i);
            ss.push(wt);           
            System.out.println("生产了:" + wt);
            try {
                Thread.sleep((int)(Math.random() * 200));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }           
        }
    }
}

class Consumer implements Runnable {
    SyncStack ss = null;
    Consumer(SyncStack ss) {
        this.ss = ss;
    }
   
    public void run() {
        for(int i=0; i<20; i++) {        //消费20个
            WoTou wt = ss.pop();
            System.out.println("消费了: " + wt);
            try {
                Thread.sleep((int)(Math.random() * 1000));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }           
        }
    }
}