java多线程基础一

1. 创建线程的几种方式:

public class ThreadDemo1 extends Thread{
 public void run(){
  System.out.println("创建线程1:"+getName());
 }
}

public class RunnableDemo implements Runnable {
 @Override
 public void run() {
  System.out.println("创建线程2:"+Thread.currentThread().getName());
 }
}

执行线程的类如下:

public class ThreadDemo2 {
 public static void main(String[] args) {
  RunnableDemo r1 = new RunnableDemo();
  Thread t1 = new Thread(r1,"线程1实现Runnable接口");
  Thread t2 = new ThreadDemo1();
  t2.setName("线程2继承自Thread类");
  Thread t3 = new Thread(new Runnable() {
   @Override
   public void run() {
    System.out.println("创建线程3:创建一个Thread内部类,内部类中实现了Runnabe接口");
   }
  });
  Thread t4 = new Thread(){
   public void run(){
    System.out.println("创建线程4:创建一个Thread内部类,重写run方法");
   }
  };
  //启动线程
  t1.start();
  t2.start();
  t3.start();
  t4.start();
 }
}

控制台打印如下:
创建线程2:线程1实现Runnable接口
创建线程1:线程2继承自Thread类
创建线程3:创建一个Thread内部类,内部类中实现了Runnabe接口
创建线程4:创建一个Thread内部类,重写run方法


2.线程的启动与停止
    1)线程的启动 start()方法
    2)线程的停止 stop()  这个会使线程戛然而止,不要使用;
        
用interrupt()方法停止线程,如下:
public class ThreadDemo1 extends Thread{
 public static void main(String[] args) {
  ThreadDemo1 td1 = new ThreadDemo1();
  System.out.println("线程开始执行");
  td1.start();
  try {
   Thread.sleep(3000);
  } catch (InterruptedException e) {//捕获异常InterruptedException
   e.printStackTrace();
  }
  System.out.println("执行Interrupted...");
  td1.interrupt();
  try {
   Thread.sleep(3000);
  } catch (InterruptedException e) {
   e.printStackTrace();
  }
  System.out.println("stop application...");
 }
 public void run(){
  while(true){                
   System.out.println("Thread running...");
   long l = System.currentTimeMillis();
   while(System.currentTimeMillis()-l<1000){
    //停止一秒,减少控制台打印(思考为什么不用Thread.sleep(1000))
   }
  }
 }
}

控制台打印如下:
线程开始执行
Thread running...
Thread running...
Thread running...
Thread running...
执行Interrupted...   //这里执行了td1.interrupt();  线程还是没有中止,继续执行(由手动强行中止)。所以interrupt();方法并不能停止我们的线程
Thread running...
Thread running...
Thread running...
stop application...
Thread running...
Thread running...

改动代码,如下:
public void run(){
  while(!this.isInterrupted()){
   System.out.println("Thread running...");
   long l = System.currentTimeMillis();
   while(System.currentTimeMillis()-l<1000){
    //停止一秒,减少控制台打印(思考为什么不用Thread.sleep(1000))
   }
  }
 }
控制台打印如下:

线程开始执行
Thread running...
Thread running...
Thread running...
Thread running...
执行Interrupted...
stop application...
可以看到线程正常停止了。

再次改动代码,如下
public void run(){
  while(!this.isInterrupted()){
   System.out.println("Thread running...");
//   long l = System.currentTimeMillis();
//   while(System.currentTimeMillis()-l<1000){
//    //停止一秒,减少控制台打印(思考为什么不用Thread.sleep(1000))
//   }
   try {
    Thread.sleep(1000);   //如果使用了interrupt()方法,1.中断状态被清除(是clear),所以线程的 isInterrupted()方法不能被正确的表示中断状态;
                                                                                //2.收到一个InterruptedException  它被中断了
   } catch (InterruptedException e) {
    e.printStackTrace();
   }
  }
 }

控制台打印结果:
线程开始执行
Thread running...
Thread running...
Thread running...
Thread running...
执行Interrupted...
Thread running...
java.lang.InterruptedException: sleep interrupted
 at java.lang.Thread.sleep(Native Method)
 at ThreadDemo1.run(ThreadDemo1.java:29)
Thread running...
Thread running...
stop application...
Thread running...

可以看到线程并没有中断,而且还抛出了InterruptedException 异常




正确的中止线程的方式:设置退出旗标

public class ThreadExitDemo implements Runnable{
 volatile boolean flag = true;
 public void run(){
  while(flag){
   try {
    Thread.sleep(1000);
   } catch (InterruptedException e) {
    e.printStackTrace();
   }
   for(int i = 0;i<5;i++){
    System.out.println("Thread["+i+"] running...");
   }
  }
  System.out.println("线程结束了!");
 }
}


写main方法测试,如下:


  ThreadExitDemo te = new ThreadExitDemo();
  Thread th1 = new Thread(te);
  th1.start();
  try {
   Thread.sleep(3000);
  } catch (InterruptedException e) {
   e.printStackTrace();
  }
  te.flag = false;


控制台打印如下:

Thread[0] running...
Thread[1] running...
Thread[2] running...
Thread[3] running...
Thread[4] running...
Thread[0] running...
Thread[1] running...
Thread[2] running...
Thread[3] running...
Thread[4] running...
Thread[0] running...
Thread[1] running...
Thread[2] running...
Thread[3] running...
Thread[4] running...
线程结束了!

如上 ,设置退出旗标能正常退出线程。














;