实现多线程

简介: 进程和线程进程:是正在运行的程序1. 是系统进行资源分配和调用的独立单位2. 每一个进程都有它自己的内存空间和系统资源线程:是进程中的单个顺序控制流,是一条执行路径1. 单线程:一个进程如果只有一条执行路径,则称为单线程程序2. 多线程:一个进程如果有多条执行路径,则称为多线程程序

实现多线程方式一:继承Thread类

方法介绍

方法名            说明

void run()          在线程开启后,此方法将被调用执行

void start()        使此线程开始执行,Java虚拟机会调用run方法()


实现步骤

1. 定义一个类 MyThread 继承 Thread类

2. 在 MyThread类 中重写run()方法

3. 创建 MyThread类 的对象

4. 启动线程


代码演示

public class MyThread extends Thread {

@Override

public void run() {

// super.run();

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

System.out.println(i);

}

}

}

package com.geekdatas;

/*

方式1: 继承Thread类

1、定义一个MyThread继承Thread类

2、在MyThread类中重写run()方法

3、创建MyThread类的对象

4、启动线程

*/

public class MyThreadDemo {

public static void main(String[] args) {

MyThread my1 = new MyThread();

MyThread my2 = new MyThread();


// 还是单线程

// my1.run();

// my2.run();

//void start() 导致此线程开始执行; Java虚拟机调用此线程的run方法

my1.start();

my2.start();

}

}



设置和获取线程名称


方法介绍

方法名                                    说明

void setName(String name)           将此线程的名称更改为等于参数name

String getName()                          返回此线程的名称

Thread currentThread()                 返回对当前正在执行的线程对象的引用

代码演示

public class MyThread extends Thread {

@Override

public void run() {

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

// String getName()返回此线程的名称

System.out.println(getName() + ":" + i);

}

}

}

public class MyThreadDemo {

public static void main(String[] args) {

MyThread my1 = new MyThread();

MyThread my2 = new MyThread();

my1.start();

my2.start();

}

}源码分析(通过无参构造方法创建线程对象的情况):

// 访问了父类的无参构造方法

public Thread() {

this((ThreadGroup)null, (Runnable)null, "Thread-" + nextThreadNum(),

0L);

}

---------------------------------------------------------

private static synchronized int nextThreadNum() {

return threadInitNumber++;// 0,1,......

}

private static int threadInitNumber;// 默认值从0开始

------------------------------------------------------------

// 无参构造方法,调用本类的其他构造方法

public Thread(ThreadGroup group, Runnable target, String name, long

stackSize) {

this(group, target, name, stackSize, (AccessControlContext)null,

true);

}

-------------------------------------------------------------

// 只看部分源代码

private Thread(ThreadGroup g, Runnable target, String name, long stackSize,

AccessControlContext acc, boolean inheritThreadLocals) {

......

if (name == null) {// name为空报异常

throw new NullPointerException("name cannot be null");

} else {

this.name = name;

......

}

}

通过 this.name = name; 发现有一个成员变量

private volatile String name;

---------------------------------------------------------

// getNmae里面就返回了成员变量this.name的值,所以我们输出的时候调用getNmae能得到

Thread-0,Thread-1......

public final String getName() {

return this.name;

}

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(getName() + ":" + i);

}

}

}



/*

Thread类中获取和设置线程名称的方法:

void setName(String name):将此线程的名称更改为等于参数name

String getName():返回此线程的名称

Thread currentThread():返回对当前正在执行的线程对象的引用

*/

public class MyThreadDemo {

public static void main(String[] args) {

/*

MyThread my1 = new MyThread();

MyThread my2 = new MyThread();

// void setName(String name)将此线程的名称更改为等于参数name

my1.setName("高铁");

my2.setName("飞机");

*/

MyThread my1 = new MyThread("高铁");

MyThread my2 = new MyThread("飞机");

my1.start();

my2.start();

// Thread currentThread():返回对当前正在执行的线程对象的引用

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

}

}



线程优先级

线程调度

两种调度方式

分时调度模型:所有线程轮流使用 CPU 的使用权,平均分配每个线程占用 CPU       的时间片

抢占式调度模型:优先让优先级高的线程使用 CPU,如果线程的优先级相同,        那么会随机选择一个,优先级高的线程获取的 CPU 时间片相对多一些

Java使用的是抢占式调度模型

随机性

假如计算机只有一个 CPU,那么 CPU 在某一个时刻只能执行一条指令,线程只有得        到CPU时间片,也就是使用权,才可以执行指令。所以说多线程程序的执行是有随        机性,因为谁抢到CPU的使用权是不一定的


优先级相关方法

方法名                                    说明

final int

getPriority()                                  返回此线程的优先级


final void                                      更改此线程的优先级

setPriority(int                                线程默认优先级是5;线程优先级的范围是:1~10

newPriority)                                  线程优先级高仅仅表示线程获取的CPU时间片的几率高,但是要                                                          在次数比较多,或者多次运行的时候才能看到你想要的效果


代码演示


public class ThreadPriority extends Thread {

@Override

public void run() {

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

System.out.println(getName() + ":" + i);

}

}

}

public class ThreadPriorityDemo {

public static void main(String[] args) {

ThreadPriority tp1 = new ThreadPriority();

ThreadPriority tp2 = new ThreadPriority();

ThreadPriority tp3 = new ThreadPriority();

tp1.setName("高铁");

tp2.setName("飞机");

tp3.setName("汽车");

//public final int getPriority():返回此线程的优先级

System.out.println(tp1.getPriority()); //5

System.out.println(tp2.getPriority()); //5

System.out.println(tp3.getPriority()); //5

//public final void setPriority(int newPriority):更改此线程的优先级

// tp1.setPriority(10000); //IllegalArgumentException

System.out.println(Thread.MAX_PRIORITY); //10

System.out.println(Thread.MIN_PRIORITY); //1

System.out.println(Thread.NORM_PRIORITY); //5

//设置正确的优先级

tp1.setPriority(5);

tp2.setPriority(10);

tp3.setPriority(1);

tp1.start();

tp2.start();

tp3.start();

}

}


线程控制

相关方法

方法名                                        说明

static void sleep(longmillis)                使当前正在执行的线程停留(暂停执行)指定的毫秒数

void join()                                          等待这个线程死亡(其他线程必须等待这个线程执行完毕才                                                           有机会执行)

void setDaemon(booleanon)               将此线程标记为守护线程,当运行的线程都是守护线程时,                                                           Java虚拟机将退出


代码演示

sleep演示

package com.geekdatas;

public class ThreadSleep extends Thread {

@Override

public void run() {

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

System.out.println(getName() + ":" + i);

}

}

}

---------------------------------------------------------------

package com.geekdatas;

/*

static void sleep(long millis)使当前正在执行的线程停留(暂停执行)指定的毫秒

*/

public class ThreadSleepDemo {

public static void main(String[] args) {

ThreadSleep ts1 = new ThreadSleep();

ThreadSleep ts2 = new ThreadSleep();

ThreadSleep ts3 = new ThreadSleep();

ts1.setName("曹操");

ts2.setName("刘备");

ts3.setName("孙权");

ts1.start();

ts2.start();

ts3.start();

}

}

-------------------------------------------------------

package com.geekdatas;

public class ThreadSleep extends Thread {

@Override

public void run() {

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

System.out.println(getName() + ":" + i);

try {

Thread.sleep(1000);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

}


join演示

package com.geekdatas;

public class ThreadJoin extends Thread {

@Override

public void run() {

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

System.out.println(getName() + ":" + i);

}

}

}

----------------------------------------------------------

package com.geekdatas;

/*

void join():等待这个线程死亡(其他线程必须等待这个线程执行完毕才有机会执行)

*/

public class ThreadJoinDemo {

public static void main(String[] args) {

ThreadJoin tj1 = new ThreadJoin();

ThreadJoin tj2 = new ThreadJoin();

ThreadJoin tj3 = new ThreadJoin();

tj1.setName("康熙");

tj2.setName("四阿哥");

tj3.setName("八阿哥");

tj1.start();

try {

tj1.join();// 等待这个线程死亡,只有tj1执行完了以后,其他线程才有机会

执行

} catch (InterruptedException e) {

e.printStackTrace();

}

tj2.start();

tj3.start();

}

}


Daemon演示

package com.geekdatas;

public class ThreadDaemon extends Thread {

@Override

public void run() {

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

System.out.println(getName() + ":" + i);

}

}

}

--------------------------------------------------------------------

package com.geekdatas;

/*

void setDaemon(boolean on):将此线程标记为守护线程,当运行的线程都是守护线程

时,Java虚拟机将退出

*/

public class ThreadDeamonDemo {

public static void main(String[] args) {

ThreadDaemon td1 = new ThreadDaemon();

ThreadDaemon td2 = new ThreadDaemon();

td1.setName("关羽");

td2.setName("张飞");

// 设置主线程为刘备

Thread.currentThread().setName("刘备");

// 设置守护线程 (主线程挂掉,其他线程也会挂掉,因为Java虚拟机将退出 注意:

其他不一定立即挂掉)

td1.setDaemon(true);

td2.setDaemon(true);

td1.start();

td2.start();

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

System.out.println(Thread.currentThread().getName() + ":" +

i);

}

}

}





目录
相关文章
|
7月前
|
并行计算 调度 UED
为什么要用多线程?
为什么要用多线程?
72 0
|
网络协议 安全
libev与多线程
libev与多线程
libev与多线程
|
7月前
|
Web App开发 IDE Java
什么是多线程
什么是多线程
49 3
|
7月前
|
Java API 调度
多线程知识篇
多线程知识篇
|
7月前
|
安全 Java C#
C#多线程详解
C#多线程详解
64 0
|
7月前
|
前端开发 Java
|
安全 Linux C++
C++多线程
C++多线程
55 1
|
7月前
|
C#
[C#] 多线程的使用
[C#] 多线程的使用
47 0
多线程
java多线程是指在程序中并发执行多个指令流,每个指令流都称为一个线程,彼此间互相独立。Java中所有变量都储存在主存中,对于所有线程都是共享的。Java中的多线程可以通过继承Thread类或者实现Runnable接口来创建,然后通过start()方法来启动线程。Java中的多线程可以提高程序的并发性和执行效率。