线程笔记
1.java支持多线程机制。并且java已经将多线程实现了,我们只需要继承就行了。
第一种方式:
编写一个类,直接继承java.lang.Thread,重写run方法。
// 定义线程类 public class MyThread extends Thread{ public void run(){ } } // 创建线程对象 MyThread t = new MyThread(); // 启动线程。 t.start();
例:
/* 实现线程的第一种方式: 编写一个类,直接继承java.lang.Thread,重写run方法。 怎么创建线程对象? new就行了。 怎么启动线程呢? 调用线程对象的start()方法。 */ public class ThreadTest02 { public static void main(String[] args) { // 这里是main方法,这里的代码属于主线程,在主栈中运行。 // 新建一个分支线程对象 MyThread t = new MyThread(); // 启动线程 //t.run(); // 不会启动线程,不会分配新的分支栈。(这种方式就是单线程。) // start()方法的作用是:启动一个分支线程,在JVM中开辟一个新的栈空间,这段代码任务完成之后,瞬间就结束了。 // 这段代码的任务只是为了开启一个新的栈空间,只要新的栈空间开出来,start()方法就结束了。线程就启动成功了。 // 启动成功的线程会自动调用run方法,并且run方法在分支栈的栈底部(压栈)。 // run方法在分支栈的栈底部,main方法在主栈的栈底部。run和main是平级的。 t.start(); // 这里的代码还是运行在主线程中。 for(int i = 0; i < 1000; i++){ System.out.println("主线程--->" + i); } } } class MyThread extends Thread { @Override public void run() { // 编写程序,这段程序运行在分支线程中(分支栈)。 for(int i = 0; i < 1000; i++){ System.out.println("分支线程--->" + i); } } }
第二种方式:
编写一个类,实现java.lang.Runnable接口,实现run方法。
// 定义一个可运行的类 public class MyRunnable implements Runnable { public void run(){ } } // 创建线程对象 Thread t = new Thread(new MyRunnable()); // 启动线程 t.start();
例1:
/* 实现线程的第二种方式,编写一个类实现java.lang.Runnable接口。 */ public class ThreadTest03 { public static void main(String[] args) { // 创建一个可运行的对象 //MyRunnable r = new MyRunnable(); // 将可运行的对象封装成一个线程对象 //Thread t = new Thread(r); Thread t = new Thread(new MyRunnable()); // 合并代码 // 启动线程 t.start(); for(int i = 0; i < 100; i++){ System.out.println("主线程--->" + i); } } } // 这并不是一个线程类,是一个可运行的类。它还不是一个线程。 class MyRunnable implements Runnable { @Override public void run() { for(int i = 0; i < 100; i++){ System.out.println("分支线程--->" + i); } } }
例2:
/* 采用匿名内部类 */ public class ThreadTest04 { public static void main(String[] args) { // 创建线程对象,采用匿名内部类方式。 // 这是通过一个没有名字的类,new出来的对象。 Thread t = new Thread(new Runnable(){ @Override public void run() { for(int i = 0; i < 100; i++){ System.out.println("t线程---> " + i); } } }); // 启动线程 t.start(); for(int i = 0; i < 100; i++){ System.out.println("main线程---> " + i); } } }
注意:第二种方式实现接口比较常用,因为一个类实现了接口,它还可以去继承
	其它的类,更灵活。
2.关于线程对象的生命周期
新建状态 就绪状态 运行状态 阻塞状态 死亡状态

3.获取当前线程对象或线程名称 修改线程名称
/* 1、怎么获取当前线程对象? Thread t = Thread.currentThread(); 返回值t就是当前线程。 2、获取线程对象的名字 String name = 线程对象.getName(); 3、修改线程对象的名字 线程对象.setName("线程名字"); 4、当线程没有设置名字的时候,默认的名字有什么规律?(了解一下) Thread-0 Thread-1 Thread-2 Thread-3 ..... */
4.关于线程的sleep方法:
 static void sleep(long millis)
    1、静态方法:Thread.sleep(1000);
    2、参数是毫秒
    3、作用:让当前线程进入休眠,进入“阻塞状态”,放弃占有CPU时间片,让给其它线程使用。
        这行代码出现在A线程中,A线程就会进入休眠。
        这行代码出现在B线程中,B线程就会进入休眠。
    4、Thread.sleep()方法,可以做到这种效果:
        间隔特定的时间,去执行一段特定的代码,每隔多久执行一次。
5.sleep面试题
/* 关于Thread.sleep()方法的一个面试题: */ public class ThreadTest07 { public static void main(String[] args) { // 创建线程对象 Thread t = new MyThread3(); t.setName("t"); t.start(); // 调用sleep方法 try { // 问题:这行代码会让线程t进入休眠状态吗? t.sleep(1000 * 5); // 在执行的时候还是会转换成:Thread.sleep(1000 * 5); // 这行代码的作用是:让当前线程进入休眠,也就是说main线程进入休眠。 // 这样代码出现在main方法中,main线程睡眠。 } catch (InterruptedException e) { e.printStackTrace(); } // 5秒之后这里才会执行。 System.out.println("hello World!"); } } class MyThread3 extends Thread { public void run(){ for(int i = 0; i < 10000; i++){ System.out.println(Thread.currentThread().getName() + "--->" + i); } } }
6.终止线程的睡眠:
终止t线程的睡眠(这种终断睡眠的方式依靠了java的异常处理机制。)
        t.interrupt(); //线程t的睡眠终止
7.终止一个线程的执行:
1.t.stop(); // 已过时(不建议使用。)
这种方式存在很大的缺点:容易丢失数据。因为这种方式是直接将线程杀死了,线程没有保存的数据将会丢失。不建议使用。
  2.写一个布尔标记,利用布尔值的改变来控制线程结束。
/* 怎么合理的终止一个线程的执行。这种方式是很常用的。 */ public class ThreadTest10 { public static void main(String[] args) { MyRunable4 r = new MyRunable4(); Thread t = new Thread(r); t.setName("t"); t.start(); // 模拟5秒 try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } // 终止线程 // 你想要什么时候终止t的执行,那么你把标记修改为false,就结束了。 r.run = false; } } class MyRunable4 implements Runnable { // 打一个布尔标记 boolean run = true; @Override public void run() { for (int i = 0; i < 10; i++){ if(run){ System.out.println(Thread.currentThread().getName() + "--->" + i); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } }else{ // return就结束了,你在结束之前还有什么没保存的。 // 在这里可以保存呀。 //save.... //终止当前线程 return; } } } }
本文来自博客园,作者:guoyuxin3,转载请注明原文链接:https://www.cnblogs.com/guoyuxin3/p/15082974.html

 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号