Java--线程(一)(创建线程的方式及线程常用的几个方法)
一、什么是线程
线程,又称轻量级进程。
程序中的一个顺序控制流程,同时也是cpu的基本调度单位。
进程由多个线程组成,彼此间完成完成不同的工作,交替执行,称为多线程。
例如:迅雷是一个进程,当中的多个下载任务即是多个线程
二、线程和进程的区别
进程是操作系统资源分配的基本单位,线程是cpu的基本调度单位。
一个程序运行后至少有一个进程。
一个进程可以包含多个线程,但是至少需要一个线程
进程间不能共享数据段地址,但同进程的线程之间可以
三、线程的组成及特点
任何一个线程都具有基本的组成部分:
1.cpu时间片:操作系统会为每个线程分配执行时间。
2.运行数据:
堆空间:存储线程需要使用的对象,多个线程可以共享堆中的对象
栈空间:存储线程需使用的局部编码,每个线程都拥有独立的栈
3.线程的逻辑代码
线程的特点:
1.线程抢占式执行:效率高;可以防止单一线程长时间独占cpu
2.在单核cpu中,宏观上同时执行,微观上顺序执行
四、创建线程的方式
1、继承Thread类 重写run()方法
获取线程名称:第一种方法:用this.getid() 和 this.getName() 获取线程的ID和名称
第二种方法:用this.currentThread() 获取当前线程
线程.setName();给线程名称赋值
注意:线程的启动 用 start() 方法
线程的名称可以修改 线程的ID不可修改
package com.monv.Thread; /** * 创建线程类 继承 Thread * @author Administrator * */ public class MyThread extends Thread{ public MyThread() { // TODO Auto-generated constructor stub } public MyThread(String name){ super(name); } @Override public void run() { for(int i = 0;i<100;i++){ //1.第一种方法 用this.getid() 和 this.getName() 获取线程的ID和名称 // System.out.println("线程ID:"+this.getId()+"线程名称:"+this.getName()+"子线程执行-------"+i); //2.第二种方法 用this.currentThread() 获取当前线程 System.out.println("线程ID:"+this.currentThread().getId()+" 线程名称:"+this.currentThread().getName()+" 子线程执行------"+i); } } } --------------------------------------------------------- package com.monv.Thread; /** * 测试线程 main是主线程 * @author Administrator * */ public class TestThread { public static void main(String[] args) { //1.创建线程 MyThread testMyThread = new MyThread("这是第一个子线程"); //2.启动线程,用Start,不能用Run //修改线程的名称 要写在线程执行前 // testMyThread.setName("这是第一个子线程"); testMyThread.start(); MyThread testMyThread2 = new MyThread("这是第二个子线程"); //2.启动线程,用Start,不能用Run //修改线程的名称 要写在线程执行前 // testMyThread2.setName("这是第二个子线程"); testMyThread2.start(); //主线程执行 for (int i = 0; i <100; i++) { System.out.println("主线程执行=============="+i); } } }
2.实现Runnable接口 重写run()方法
注意:Runable也可以用内部类的方法实现
package com.monv.Thread; public class MyRunnable implements Runnable{ @Override public void run() { for (int i = 0; i<100 ;i++){ System.out.println(Thread.currentThread().getName()+"++++++++++"+i); } } } ------------------------------------------------------ package com.monv.Thread; public class TestRunnable { public static void main(String[] args) { //1.创建MyRunnable对象,表示线程要执行的功能 MyRunnable runnable = new MyRunnable(); //2.创建线程 Thread thread = new Thread(runnable, "我的线程"); //3.执行 thread.start(); for (int i = 0; i < 100;i++){ System.out.println("main------------"+i); } } } ------------------------------------------------- -------------匿名内部类方法实现--------------------- package com.monv.Thread; public class TestRunnable { public static void main(String[] args) { //创建匿名内部类 Runnable runnable = new Runnable() { @Override public void run() { for (int i = 0; i < 100;i++){ System.out.println(Thread.currentThread().getName()+"++++++++++++"+i); } } }; Thread thread = new Thread(runnable, "我的线程"); thread.start(); for (int i = 0; i < 100;i++){ System.out.println("main------------"+i); } } }
五、线程的状态
六、常见的方法
1.休眠:public static void sleep(long millis); 当前线程主动休眠millis毫秒
2.放弃:public static void yield(); 当前主线程主动放弃时间片,回到就绪状态,竞争下一次时间片
3.加入:public final void join();允许其他线程加入到当前线程中
--------1.sleep----------- package com.monv.Thread; public class SleepThread extends Thread{ @Override public void run() { for (int i =0 ;i<10 ;i++){ System.out.println(Thread.currentThread().getName()+"............."+i); try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }
---------测试------------- package com.monv.Thread; public class TestSleep { public static void main(String[] args) { SleepThread s1 = new SleepThread(); s1.start(); SleepThread s2 = new SleepThread(); s2.start(); } } --------2.yield----------- package com.monv.Thread; public class YieldThread extends Thread{ @Override public void run() { for(int i =0;i< 10;i++){ System.out.println(Thread.currentThread().getName()+"+++++++++++"+i); //主动放弃cpu Thread.yield(); } } }
---------测试------------------ package com.monv.Thread; public class TestYield { public static void main(String[] args) { YieldThread y1 = new YieldThread(); YieldThread y2 = new YieldThread(); y1.start(); y2.start(); } } --------3.join----------- package com.monv.Thread; public class JoinThread extends Thread{ @Override public void run() { for (int i = 0; i < 30; i++) { System.out.println(Thread.currentThread().getName()+"........."+i); try { Thread.sleep(500); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }
----------测试--------------- package com.monv.Thread; public class TestJoin { public static void main(String[] args) { JoinThread jo1 = new JoinThread(); jo1.start(); try { jo1.join();//把j1加入当前线程(主线程main),并阻塞当前线程,直到加入线程执行完毕当前线程才会继续执行 } catch (InterruptedException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } //主线程 for (int i =0;i<20;i++){ System.out.println(Thread.currentThread().getName()+"......"+i); try { Thread.sleep(300); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }
七、线程等待