赞
踩
一个顺序的单一的程序执行流程就是一个线程。代码一句一句的有先后顺序的执行。
多个单一顺序执行的流程并发运行。造成"感官上同时运行"的效果。
多个线程实际运行是走走停停的。线程调度程序会将CPU运行时间划分为若干个时间片段并尽可能均匀的分配给每个线程,拿到时间片的线程被CPU执行这段时间。当超时后线程调度程序会再次分配一个时间片段给一个线程使得CPU执行它。如此反复。由于CPU执行时间在纳秒级别,我们感觉不到切换线程运行的过程。所以微观上走走停停,宏观上感觉一起运行的现象成为并发运行!
定义一个线程类,重写run方法,在其中定义线程要执行的任务(希望和其他线程并发执行的任务)。
注:启动该线程要调用该线程的start方法,而不是run方法!!!
package thread; /** * 多线程 * 线程:程序中一个单一的顺序执行流程 * 多线程:多个单一顺序执行流程"同时"执行 * * 多线程改变了代码的执行方式,从原来的单一顺序执行流程变为多个执行流程"同时"执行。 * 可以让多个代码片段的执行互不打扰。 * * 线程之间是并发执行的,并非真正意义上的同时运行。 * 常见线程有两种方式: * 1:继承Thread并重写run方法 * */ public class ThreadDemo1 { public static void main(String[] args) { //创建两个线程 Thread t1 = new MyThread1(); Thread t2 = new MyThread2(); /* 启动线程,注意:不要调用run方法!! 线程调用完start方法后会纳入到系统的线程调度器程序中被统一管理。 线程调度器会分配时间片段给线程,使得CPU执行该线程这段时间,用完后 线程调度器会再分配一个时间片段给一个线程,如此反复,使得多个线程 都有机会执行一会,做到走走停停,并发运行。 线程第一次被分配到时间后会执行它的run方法开始工作。 */ t1.start(); t2.start(); } } /** * 第一种创建线程的优点: * 结构简单,利于匿名内部类形式创建。 * * 缺点: * 1:由于java是单继承的,这会导致继承了Thread就无法再继承其他类去复用方法 * 2:定义线程的同时重写了run方法,这等于将线程的任务定义在了这个线程中导致 * 线程只能干这件事。重(chong)用性很低。 */ class MyThread1 extends Thread{ public void run(){ for (int i=0;i<1000;i++){ System.out.println("hello姐~"); } } } class MyThread2 extends Thread{ public void run(){ for (int i=0;i<1000;i++){ System.out.println("来了~老弟!"); } } }
第一种创建线程的方式
优点:
在于结构简单,便于匿名内部类形式创建。
缺点:
package thread; /** * 第二种创建线程的方式 * 实现Runnable接口单独定义线程任务 */ public class ThreadDemo2 { public static void main(String[] args) { //实例化任务 Runnable r1 = new MyRunnable1(); Runnable r2 = new MyRunnable2(); //创建线程并指派任务 Thread t1 = new Thread(r1); Thread t2 = new Thread(r2); t1.start(); t2.start(); } } class MyRunnable1 implements Runnable{ public void run() { for (int i=0;i<1000;i++){ System.out.println("你是谁啊?"); } } } class MyRunnable2 implements Runnable{ public void run() { for (int i=0;i<1000;i++){ System.out.println("开门!查水表的!"); } } }
package thread; /** * 使用匿名内部类完成线程的两种创建 */ public class ThreadDemo3 { public static void main(String[] args) { Thread t1 = new Thread(){ public void run(){ for(int i=0;i<1000;i++){ System.out.println("你是谁啊?"); } } }; // Runnable r2 = new Runnable() { // public void run() { // for(int i=0;i<1000;i++){ // System.out.println("我是查水表的!"); // } // } // }; //Runnable可以使用lambda表达式创建 Runnable r2 = ()->{ for(int i=0;i<1000;i++){ System.out.println("我是查水表的!"); } }; Thread t2 = new Thread(r2); t1.start(); t2.start(); } }
java中的代码都是靠线程运行的,执行main方法的线程称为"主线程"。
线程提供了一个方法:
static Thread currentThread()
该方法可以获取运行这个方法的线程
package thread; /** * java中所有的代码都是靠线程执行的,main方法也不例外。JVM启动后会创建一条线程来执行main * 方法,该线程的名字叫做"main",所以通常称它为"主线程"。 * 我们自己定义的线程在不指定名字的情况下系统会分配一个名字,格式为"thread-x"(x是一个数)。 * * Thread提供了一个静态方法: * static Thread currentThread() * 获取执行该方法的线程。 * */ public class CurrentThreadDemo { public static void main(String[] args) { /* 后期会学习到一个很重要的API:ThreadLocal,它可以使得我们在一个线程上跨越多个 方法时共享数据使用,其内部要用到currentThread方法来辨别线程。 如spring的事物控制就是靠ThreadLocal实现的。 */ Thread main = Thread.currentThread();//获取执行main方法的线程(主线程) System.out.println("线程:"+main); dosome();//主线程执行dosome方法 } public static void dosome(){ Thread t = Thread.currentThread();//获取执行dosome方法的线程 System.out.println("执行dosome方法的线程是:"+t); } }
package thread; /** * 获取线程相关信息的一组方法 */ public class ThreadInfoDemo { public static void main(String[] args) { Thread main = Thread.currentThread();//获取主线程 String name = main.getName();//获取线程的名字 System.out.println("名字:"+name); long id = main.getId();//获取该线程的唯一标识 System.out.println("id:"+id); int priority = main.getPriority();//获取该线程的优先级 System.out.
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。