黑马程序员——线程

---------------------- android培训java培训、期待与您交流! ----------------------

 


1、什么是进程

进程是指计算机正在运行的程序,一个进程至少有一个线程。

2、什么是线程

线程是一个程序里面不同的执行路径。

main方法本身可以称为主线程。

下面的两个示例可以展示线程的执行过程。
  
   示例1

  public class ThreadExer {
  //主线程main
 public static void main(String[] args) { 
   
  Counter counter = new Counter();   
                        //使用线程首先实例化,调用的是构造函数Thread(Runnable targer)。
  Thread thread = new Thread(counter); 
  thread.start();            //线程启动,执行run()方法。
  for (int i = 0; i < 100; i++) {
   System.out.println("主线程数:" + i);
  }
 }
}
//执行run()方法有两种,一、实现Runnable接口  二、继承Thread类

   public class Counter implements Runnable {  

   //子线程
 public void run() {              //run()方法是线程体,准备要实现的功能。
  for (int i = 0; i < 100; i++) {
   System.out.println("子线程数:" + i);
  }
 }
}

   示例2

   与示例1基本相同

//Thread原本已经实现Runnable接口,所以Thread类里也有run()方法

   public class Counter extends Thread{  

//继承就不用实例化线程  Thread thread=new Thread(Runnable targer);
  
结果显示:主线程和子线程同时执行,穿插输出。

注:实现Runnable接口,优先于继承Thread类。因为接口拥有更高的扩展性。

2、线程控制基本方法

Thread.sleep(long millis)方法: 将当前线程睡眠指定毫秒数,它是Thread的静态方法,直接用类调用。

抛出中断线程异常:throws InterruptedException(重写的方法不能抛出比被重写方法不同的异常)。

interrupt()中断线程方法(和抛出中断线程异常搭配使用),但此方法比较粗暴,不等线程结束直接中断。其实可以判断run()方法来结束进程,run()方法结束进程就结束。

示例3

import java.util.Date;

public class Counter implements Runnable {// extends Thread{

 public void run() {
  boolean bool = true;
  while (bool) {
   System.out.println(new Date());
   try {
    Thread.sleep(1000);
   } catch (InterruptedException e) {
    bool = false;
   }
  }

join()方法:合并某个线程

过程:先执行run()方法,然后遇到join()暂停主线程运行,等子线程运行结束会与主线程合并,相当于方法调用。

示例4

//主线程
public class ThreadExer {

 public static void main(String[] args) {
  Counter counter = new Counter("subThread");
  counter.start();//调用run()方法
  try {
   counter.join();//暂停执行,run()方法执行结束,合并counter,执行主线程
  
  } catch (InterruptedException e) {
  }
  for (int i = 0; i < 10; i++) {   
   System.out.println("i am main thread");
  }
  
 }
}

//子线程
public class Counter extends Thread{

 public Counter() {
 }

 public Counter(String value) {
  super(value);
 }

 public void run() {

   for (int i = 1; i <= 10; i++) {
    System.out.println("i am " + getName());  
   try {
    Thread.sleep(1000);//每次停1秒
   } catch (InterruptedException e) {
    e.getMessage();
   }
  }  
 }
}


yield()静态方法:让出CPU,给其他线程执行的机会(只让出一会儿)。

例:

public class ThreadExer{
    public static void main(String[] args){
 Thread thread1=new Thread(new Counter());
 Thread thread2=new Thread(new Counter());
 thread1.start();
 thread2.start();
    }
}

public class Counter implements Runnable{
      public void run(){
  for(int i=0;i<100;i++){
          System.out.println("counter"+i);
           if(i%10==0){
     Thread.yield();//如果能整除10,就让出一会儿CPU,让另一个线程执行。
   }   
  } 
   }
     }

priority()方法:线程的优先级用数字表示,范围1-10,一个线程默认优先级是5。

例如: Thread.MIN_PRIORITY=1     //最小优先级
      Thread.MAX_PRIORITY=10               //最大优先级
      Thread.NORM_PRIORITY=5    //默认优先级

 设置线程对象优先级
        void setPriority(int newPriority);

示例

public class ThreadExer{
    public static void main(String[] args){
 Thread thread1=new Thread(new Counter1());
 Thread thread2=new Thread(new Counter2());
 thread1.setPriority(Thread.NORM_PRIORITY+3);//设置线程1,在默认情况下提高3级
 thread1.start();
 thread2.start();
    }
}

public class Counter1 implements Runnable{
     public void run(){
 for(int i=0;i<100;i++){
        System.out.println("counter1"+i);
   }
     }
}

public class Counter2 implements Runnable{
     public void run(){
 for(int i=0;i<100;i++){
        System.out.println("counter2"+i);
   }
     }
}

线程同步

synchronized()(锁定当前对象),锁的机制。

通过给对象加“锁”,把当前对象锁定,强化加锁对象的执行完整性。

例:

public class TestSync implements Runnable {// 实现Runnable接口
 Timer timer = new Timer();// 生成对象timer

 public static void main(String[] args) {
  TestSync test = new TestSync();// 实例化本身,生成对象test,同时也实例化Timer类
  Thread t1 = new Thread(test);// 实例化线程生成对象t1
  Thread t2 = new Thread(test);// 实例化线程生成对象t2,和t1传入的是同一个对象timer
  t1.setName("t1");// 设置名字
  t2.setName("t2");
  t1.start();// 调用run()方法
  t2.start();
 }

 public void run() {
  timer.add(Thread.currentThread().getName());// currentThread()当前线程对象
 }
}

class Timer {
 private static int num = 0;

 public synchronized void add(String name) {
 // 名字为t1,加锁synchronized之后,当前对象被锁定,此方法为同步方法,t1对象解锁后,t2才执行同步方法。
  // synchronized (this) {
  num++;//t1:num=1;t2:num=2
  try {
   Thread.sleep(1);
   // t1睡眠1毫秒,暂停t1,执行t2;
   // t2睡眠1毫秒,暂停t2,再接着执行t1; t1:num=2;
  } catch (InterruptedException e) {
  }
  System.out.println(name + ", 你是第" + num + "个使用timer的线程");
  // }
 }
}

结果:未加锁之前,t1和t2都是第2个使用timer的线程。
      加锁之后,t1是第1个使用timer的线程,t2是第2个使用timer的线程。

死锁

例:

package thread.exercise;

public class ThreadDeathLock 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) {//锁着对象o1
    try {
     Thread.sleep(500);
    } catch (Exception e) {
     e.printStackTrace();
    }
    synchronized(o2) {//只有先解开o2的锁,才能再锁o2
     System.out.println("1"); 
    }
   }
  }
  if(flag == 0) {
   synchronized(o2) {//锁着对象o2
    try {
     Thread.sleep(500);
    } catch (Exception e) {
     e.printStackTrace();
    }
    synchronized(o1) {//只有先解开o1的锁,才能再锁o1
     System.out.println("0");
    }
   }
  }
 } 
 
 public static void main(String[] args) {
  ThreadDeathLock td1 = new ThreadDeathLock();
  ThreadDeathLock td2 = new ThreadDeathLock();
  td1.flag = 1;
  td2.flag = 0;
  Thread t1 = new Thread(td1);
  Thread t2 = new Thread(td2);
  t1.start();
  t2.start();
  
 }
}

注:如果一个线程调用同步方法,另一个线程调用非同步方法,就会按照线程流程执行,不会去等待同步方法解锁。
例如:一个写入方法,一个读取方法,写入方法就可以加锁,只能一个对象写入之后,下一个对象才能写入,而多个对象可以      同时读取。

---------------------- android培训java培训、期待与您交流! ----------------------

详细请查看:http://edu.csdn.net/heima

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值