进程
进程:是正在运行的程序
是系统进行资源分配和调用的独立单位
每一个进程都有它自己的内存空间和系统资源
线程
线程:是进程中的单个顺序控制流,是一条执行路径
单线程:一个进程如果只有一条执行路径,称为单线程程序
多线程:一个进程如果有多条执行路径,称为多线程程序
多线程的实现方式
方式一:继承 Thread 类
定义一个类 MyThread 继承 Thread 类
在MyThread 类中重写run()方法
创建MyThread类的对象
启动线程
//**方式一:继承 Thread 类** // 定义一个类 MyThread 继承 Thread 类 // 在MyThread 类中重写run()方法 // 创建MyThread类的对象 // 启动线程 public class MyThread extends Thread { @Override public void run() { for ( int i=0; i<100; i++ ) { System.out.println( this.getName() + " " + i ); } } //重写run方法,run方法是用来封装被线程执行的代码 }
public class Test { public static void main(String[] args) { MyThread myThread = new MyThread(); myThread.start();//启动线程 //调用run方法只是单纯调用方法,没有启动线程 //调用start方法会导致线程开始执行,Java会调用此线程的run方法 } }
run方法封装线程执行的代码,直接调用,相当于普通方法的调用
start方法启动线程,然后由JVM调用此线程的run方法
设置和获取线程的名称
Thread类中设置和获取线程名称的方法:
void setName( String name ) : 将此线程的名称改为等于参数name
String getName() : 返回此线程的名称
public class Test { public static void main(String[] args) { MyThread myThread = new MyThread(); myThread.setName("我的线程"); System.out.println(myThread.getName()); } } 输出: 我的线程 public class Test { public static void main(String[] args) { //Thread.currentThread()返回对当前正在执行的线程对象的引用 System.out.println( Thread.currentThread() ); } } 输出: Thread[main,5,main]
通过构造方法设置线程的名称:
public class MyThread extends Thread { public MyThread() { } public MyThread(String name) { super(name); } @Override public void run() { for ( int i=0; i<100; i++ ) { System.out.println( this.getName() + " " + i ); } } } public class Test { public static void main(String[] args) { MyThread myThread = new MyThread("我的线程"); System.out.println( myThread.getName() ); } } 输出: 我的线程
线程调度
线程有两种调度模式:
分时调度模型:所有线程轮流使用CPU的使用权。平均分配每个线程占用CPU的时间片
抢占式调度模式:优先让优先级高的线程使用CPU,如果线程的优先级相同,那么随机选择一个,优先级高的线程获取的CPU时间片相对多一些
Java使用的是抢占式模式调度
多线程执行具有随机性,因为谁抢到CPU的使用权不一定
Thread 类中设置和获取线程优先级的方法:
public final int getPriority(): 返回此线程的优先级
public final void setPriority( int newPriority ):更改此线程的优先级
线程的优先级具有范围:1-10,默认优先级为5
public class Test { public static void main(String[] args) { MyThread myThread1 = new MyThread(); System.out.println(myThread1.getPriority()); MyThread myThread2 = new MyThread(); myThread2.setPriority(10); MyThread myThread3 = new MyThread(); myThread3.setPriority(1); System.out.println(myThread2.getPriority()); System.out.println(myThread3.getPriority()); } } 输出: 5 10 1 System.out.println(Thread.MAX_PRIORITY); System.out.println(Thread.MIN_PRIORITY); 输出: 10 1
线程优先级高仅仅表示获取CPU时间片的几率高,并不是优先级高的线程一定每次都可以抢到CPU时间片
线程控制
sleep public class MyThread extends Thread { public MyThread() { } public MyThread(String name) { super(name); } @Override public void run() { for ( int i=0; i<100; i++ ) { System.out.println( this.getName() + " " + i ); try { Thread.sleep(1000);//线程休眠一秒 } catch (InterruptedException e) { e.printStackTrace(); } } } } join public class Test { public static void main(String[] args) { MyThread myThread1 = new MyThread(); MyThread myThread2 = new MyThread(); MyThread myThread3 = new MyThread(); myThread1.start(); try { myThread1.join();//线程一执行完成才会执行后面其他线程 } catch (InterruptedException e) { e.printStackTrace(); } myThread2.start(); myThread3.start(); } } setDaemon public class Test extends Thread { public static void main(String[] args) { MyThread myThread1 = new MyThread(); MyThread myThread2 = new MyThread(); myThread1.setDaemon(true); myThread2.setDaemon(true); myThread1.start(); myThread2.start(); Test test = new Test(); test.start(); //当test执行结束,剩下的线程都为守护线程,会直接退出 } @Override public void run() { for ( int i=0; i<10; i++ ) { System.out.println( "main" + " " + i ); } } } public class MyThread extends Thread { @Override public void run() { for ( int i=0; i<100; i++ ) { System.out.println( this.getName() + " " + i ); } } }
线程的生命周期
多线程的实现方式二
创建线程的另一种方法:声明一个实现Runnable接口的类,实现run方法。然后可以分配类的实例,在创建Thread时作为参数传递,并启动线程。
实现多线程的方法二:
1.定义一个MyRunnable类实现Runnable接口
2.在MyRunnable类中重写run方法
3.创建MyRunnable类的对象
4.创建Thread类的对象,把MyRunnable对象作为构造方法的参数
5.启动线程
public class MyRunnable implements Runnable { @Override public void run() { for ( int i=0; i<10; i++ ) { System.out.println( i ); } } } public class Test { public static void main(String[] args) { MyRunnable myRunnable = new MyRunnable(); Thread thread = new Thread(myRunnable); thread.start(); } }
给线程设置名字
thread.setName("我的线程"); System.out.println(thread.getName());
在创建线程对象时,给线程设置名字
Thread thread = new Thread(myRunnable, "我的线程~~"); System.out.println(thread.getName());
多线程的实现方案:
1.继承Thread类
2.实现Runnable接口
相对于继承Thread类,实现Runnable接口,避免了Java单继承的局限性,适合多个相同程序的代码处理同一个资源的情况,把线程和程序的代码、数据有效分离,较好的体现了面向对象的设计思想