java多线程理解_理解 Java 多线程

  • Post author:
  • Post category:java


并发与并行

并发:指两个或多个事件在同一时间段内发生。

并行:指两个或多个事件在同一时刻发生(同时发生)。

进程与线程

进程:

是指一个内存中运行的应用程序,每个进程都有一个独立的内存空间,一个应用程序可以同时运行多个进程;进程也是程序的一次执行过程,是系统运行程序的基本单位;系统运行一个程序即是一个进程从创建、运行到消亡的过程。

线程:

线程是进程中的一个执行单元,负责当前进程中程序的执行,一个进程中至少有一个线程。一个进程中是可以有多个线程的,这个应用程序也可以称之为多线程程序。

简而言之:

一个程序运行后至少有一个进程,一个进程中可以包含多个线程。

7b46fbab35755bb93b2c4472161460e0.png

42db68573cf6da04220c9b1ea40e856b.png

线程调度

分时调度:

所有线程轮流使用CPU的使用权,平均分配每个线程占用CPU的时间。

抢占式调度:

优先让优先级高的銭程使用CPU,如果线程的优先级相同,那么会随机选择一个(线程随机性),Java使用的为抢占式调度。

Java中的主线程

主线程:执行主(main)方法的线程。

单线程

单线程:Java程序中,只有一个线程,执行从main方法开始,从上到下的执行。

举例

public classStudent {public static voidmethod1() {for (int i = 0; i < 5; i++) {

System.out.println(“我正在执行Student的方法1”);

}

}public static voidmethod2() {for (int i = 0; i < 5; i++) {

System.out.println(“我正在执行Student的方法2”);

}

}publicStudent() {

}

}

public classDemo01MainThread {public static voidmain(String[] args) {

Student.method1();

Student.method2();

}

}

控制台输出:

我正在执行Student的方法1

我正在执行Student的方法1

我正在执行Student的方法1

我正在执行Student的方法1

我正在执行Student的方法1

我正在执行Student的方法2

我正在执行Student的方法2

我正在执行Student的方法2

我正在执行Student的方法2

我正在执行Student的方法2

从控制台输出可以知道,程序从上到下的执行,从方法1开始执行,到方法2开始执行。

多线程

创建多线程程序的第一种方式

创建Thread类的子类

java.lang.Thread类:是描述线程的类,我们想要实现多线程程序,就必须继承Thread类

实现步骤:

创建一个 Thread类的子类。

在Thread类的子类中重写Thread类中的run方法,设置线程任务(开启线程要做什么)。

创建Thread类的子类对象。

调用Thread类中的start方法,开启新的线程,执行run方法

void start()使该线程开始执行。Java虚拟机调用该线程的run方法。结果是两个线程并发地运行;当前线程(main线程)和另一个线程(创建的新线程,执行其run方法)。多次启动一个线程是非法的。特别是当线程已经结束执行后,不能再重新启动。Java程序属于抢占式调度,哪个线程的优先级高,哪个线程优先执行;同一个优先级,随机选择一个执行。

例子:

public class Person extendsThread {/*** 重写Thread类的run方法,设置任务*/@Overridepublic voidrun() {for (int i = 0; i < 6; i++) {

System.out.println(“我正在执行重写的run方法中的线程:” +i);

}

}

}

public classDemo02MainThread {public static voidmain(String[] args) {//创建Thread的子类对象

Thread myThread = newPerson();//调用Thread类中的start方法,开启新的线程,执行run方法

myThread.start();//main方法中的要执行的线程

for (int i = 0; i < 6; i++) {

System.out.println(“我正在执行main方法的线程:” +i);

}

}

}

控制台输出:

我正在执行main方法的线程:0我正在执行main方法的线程:1我正在执行重写的run方法中的线程:0我正在执行main方法的线程:2我正在执行重写的run方法中的线程:1我正在执行重写的run方法中的线程:2我正在执行重写的run方法中的线程:3我正在执行重写的run方法中的线程:4我正在执行重写的run方法中的线程:5我正在执行main方法的线程:3我正在执行main方法的线程:4我正在执行main方法的线程:5

多线程的原理

0baacf2c21ed192b02b30dde706dba09.png

Thread类的常用方法

publicString getName():获取当前线程名称。public voidstart():导致此线程开始执行;Java虚拟机调用此线程的run方法。public voidrun():此线程要执行的任务在此处定义代码。public static void sleep(longmillis):使当前正在执行的线程以指定的亳秒数暂停(暂时停止执行)。public static Thread currentThread()返回对当前正在执行的线程对象的引用。

getName()方法、start()方法、run()方法

public class MyThread extendsThread {

@Overridepublic voidrun() {//此线程要执行的任务

}

}

public classDemo01MyThread {public static voidmain(String[] args) {

MyThread myThread1= newMyThread();

myThread1.start();

String run1Name=myThread1.getName();

MyThread myThread2= newMyThread();

myThread2.start();

String run2Name=myThread2.getName();

MyThread myThread3= newMyThread();

myThread3.start();

String run3Name=myThread3.getName();

System.out.println(“线程1名称:” +run1Name);

System.out.println(“线程2名称:” +run2Name);

System.out.println(“线程3名称:” +run3Name);

}

}

控制台输出:

线程1名称:Thread-0线程2名称:Thread-1线程3名称:Thread-2

currentThread()方法

public class MyThread extendsThread {

@Overridepublic voidrun() {//此线程要执行的任务

System.out.println(Thread.currentThread());

}

}

public classDemo02MyThread {public static voidmain(String[] args) {

MyThread myThread1= newMyThread();

myThread1.start();

MyThread myThread2= newMyThread();

myThread2.start();

MyThread myThread3= newMyThread();

myThread3.start();

}

}

控制台输出:

Thread[Thread-0,5,main]

Thread[Thread-2,5,main]

Thread[Thread-1,5,main]

了解一下setName()方法:设置线程的名称

public classDemo03MyThread {public static voidmain(String[] args) {

MyThread myThread= newMyThread();

myThread.setName(“李华”);

myThread.start();

}

}

控制台输出:

Thread[李华,5,main]

sleep()方法

public class MyThread2 extendsThread {

@Overridepublic voidrun() {//此线程要执行的任务

for (int i = 0; i < 11; i++) {try{//参数为毫秒

Thread.sleep(1000);

}catch(InterruptedException e) {

e.printStackTrace();

}

System.out.print(“第” + i + “秒 “);

}

}

}

public classDemo01MyThread2 {public static voidmain(String[] args) {

MyThread2 thread2= newMyThread2();

thread2.start();

}

}

控制台输出:

第0秒 第1秒 第2秒 第3秒 第4秒 第5秒 第6秒 第7秒 第8秒 第9秒 第10秒

创建多线程的第二种方式

实现Runnable接口,来创建多线程。

实现步骤

创建一个 Runnable接口的实现类。

在实现类中重写 Runnable接口的run方法,设置线程任务。

创建一个 Runnable接口的实现类对象。

创建Thread类对象,构造方法中传递 Runnable接口的实现类对象。

调用 Threads类中的 start方法,开启新的线程执行run方法

举例

//创建一个 Runnable接口的实现类。

public class MyRunnable implementsRunnable {

@Overridepublic voidrun() {//在实现类中重写 Runnable接口的run方法,设置线程任务。

for (int i = 0; i < 3; i++) {

System.out.println(Thread.currentThread().getName()+ ” ~~~~~~~~~ ” +i);

}

}

}

public classDemoRunnable {public static voidmain(String[] args) {//创建一个 Runnable接口的实现类对象。

MyRunnable myRunnable = newMyRunnable();//创建Thread类对象,构造方法中传递 Runnable接口的实现类对象。

Thread thread = newThread(myRunnable);//调用 Threads类中的 start方法,开启新的线程执行run方法

thread.start();//main方法线程

for (int i = 0; i < 3; i++) {

System.out.println(Thread.currentThread().getName()+ ” ~~~~~~~~~ ” +i);

}

}

}

控制台输出:

main~~~~~~~~~ 0Thread-0 ~~~~~~~~~ 0main~~~~~~~~~ 1Thread-0 ~~~~~~~~~ 1Thread-0 ~~~~~~~~~ 2main~~~~~~~~~ 2

使用Runnable相比Thread有哪些优势

适合多个相同的程序代码的线程去共享同一个资源。

可以避兔Java中的单继承的局限性。

増加程序的健壮性,实现解耦(把设置线程任务和开启线程分开)操作,代码可以被多个线程共享,代码和线程独立。

线程池只能放入实现 Runable或 Callable类线程,不能直接放入继承 Thread的类。

内部类实现创建多线程

public class MyRunnable implementsRunnable {

@Overridepublic voidrun() {//在实现类中重写 Runnable接口的run方法,设置线程任务。

for (int i = 0; i < 3; i++) {

System.out.println(Thread.currentThread().getName()+ ” ~~~~~~~~~ ” +i);

}

}

}

public classDemoSimpleThread {public static voidmain(String[] args) {//创建一个 Runnable接口的实现类对象。

MyRunnable myRunnable = newMyRunnable();newThread(myRunnable) {

@Overridepublic voidrun() {

System.out.print(“匿名内部类的方式实现多线程的创建:”);

System.out.println(Thread.currentThread().getName()+ “线程”);

}

}.start();//main线程

System.out.println(“main线程”);

}

}

控制台输出:

main线程

匿名内部类的方式实现多线程的创建:Thread-0线程



版权声明:本文为weixin_36026440原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。