sand java_关于Java多线程

Java多线程

在学习多线程之前我们需要了解一些概念。

并发(Concurrent):指两个或多个事件在同一时间段内发生。(CPU每个小时间片执行一个线程,多个操作快速切换执行)。

并行(Parallel):指两个或多个事件在同一时刻发生。(两个线程互不抢占 CPU 资源,可以同时进行)

进程:指一个内存中运行的程序,每个进程都有一个独立的运行空间。

线程:线程是进程中的一个执行单元,负责当前进程中程序的执行,一个进程至少有一个线程,可以有多个线程。

线程的调度:分为分时调度(轮流,平均分配CPU时间),抢占式调度(优先级高的线程使用CPU)。

155fd1425be541377b598400cf8f7dcb.png

(一)创建线程类

第一种创建线程的方式(Thread类):

Java使用Thread类来代表线程,所有的线程对象必须是Thread类或其子类的实例。每个线程的作用就是完成一定的任务,实际上就是执行一段程序流即一段顺序执行的代码。通过继承Thread类来创建并启动多线程的步骤如下:

1.定义Thread类的子类,并重写该类的run()方法,该run()方法的方法体就代表了线程需要完成的任务,因此把run()方法称为线程执行体。

2.创建Thread子类的实例,即创建了线程对象。

3.调用线程对象的start()方法来启动该线程。

public class MyThread extendsThread{

@Overridepublic voidrun() {for (int i = 0; i <20 ; i++) {

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

}

}

}

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

MyThread mt= newMyThread();

mt.start();for (int i = 0; i <20 ; i++) {

System.out.println("main:"+i);//main主线程

}

}

}

*java属于抢占式调度,哪个优先级高执行哪个,同一优先级,随机选择一个执行。

上述代码多线程原理:

1.JVM首先执行main方法通向CPU的路径,这个路径叫做main线程,主线程。CPU用过这个线程,这个路径可以执行main方法。

2.new MyThread()方法在main线程内开辟一条通向CPU的新路径(即新线程),用来执行run()方法。

3.程序执行结果,即随机打印。

两个线程,一个main线程,一个新线程一起抢夺CPU的执行权(执行时间)谁抢到了谁就执行相应的代码。

多线程的内存图解:

start()方法会开辟新的栈空间,如果只是调用run()方法,只是在原来的空间中进行压栈操作而已。

5aa546e0c7669ac83b1c53d5d959a687.png

关于Thread方法中的常用方法:

构造方法:

•public Thread():分配一个新的线程对象。

•public Thread(String name):分配一个指定名字的新的线程对象。

•public Thread(Runnable target):分配一个带有指定目标(任务)的新的线程对象。

•public Thread(Runnable target,String name):分配一个带有指定目标的新的线程对象。

常用方法:

•public String getNmae():获取当前线程名称。

•public void start():导致此线程开始执行;java虚拟机调用此线程的run方法。

•public void run():此线程要执行的任务在此处定义代码。

•public static void sleep(long mills):当前正在执行的线程以指定的毫秒数暂停。(暂时停止执行)

•public static Thread currentThread():返回当前正在执行的线程的引用。(Thread.currentThread.getNname()返回当前线程名称。)

设置线程名字的两种方式:

1.使用Thread中的方法setName(name)

void setName(String name)去改变线程的名称,使之与参数name相同。

2.创建一个带参数的构造方法,参数传递线程的名称;调用父类的带参构造函方法,把线程名称传递给父类,让父类给子线程起一个名字Thread(String name)分配新的Thread 对象。

public class MyThread extendsThread{publicMyThread(){

}publicMyThread(String name){super(name);

}

@Overridepublic voidrun() {

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

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

}

}

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

MyThread thr= newMyThread();

thr.setName("哆啦A梦");//使用setName方法直接去设置线程的名字

thr.start();new MyThread("蜡笔小新").start();

System.out.println(Thread.currentThread().getName());//显示当前线程的名字

}

}

第二种创建线程的方式(Runnable):

使用Runnable接口来创建线程。方法如下:

1.定义Runnable接口的实现类,并重写该接口的run()方法,该run()方法同样是该线程的执行体。

2.创建Runnable实现类的实例,并以此实例作为Thread的target来创建Thread对象,该Thread对象才是真正的线程对象。

3.调用对象的start()方法来启动线程。

public class RunnableImpl implementsRunnable {

@Overridepublic voidrun() {for (int i = 0; i <20 ; i++) {

System.out.println(Thread.currentThread().getName()+"-->"+i);

}

}

}

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

RunnableImpl imp= newRunnableImpl();

Thread t= new Thread(imp,"哆啦A梦");

t.start();for (int i = 0; i <20 ; i++) {try{

t.sleep(1000);//调用sleep方法,使线程暂停1秒。

} catch(InterruptedException e) {

e.printStackTrace();

}

System.out.println(Thread.currentThread().getName()+"-->"+i);

}

}

}

实现Runnable接口比Thread类所具有的优势:

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

2.避免了单继承的局限性,可以去继承其他类,而不单单是Thread类

3.可扩展性高,降低了程序的耦合性(解耦)

解耦:就是创建Runnable接口实现类并完成调用这一过程,把设置线程任务和开启新线程实现了分离

实现类中,重写了Run方法:用来设置线程任务。

创建Thread类对象。调用start方法只需传递不同的实现类(run方法任务不同)的类的对象。

第三种创建线程的方式(匿名类):

匿名内部类的作用:简化代码

把子类继承父类,重写父类的方法,创建子类对象合成一步写完。

把实现类实现类接口,重写接口的方法,创建实现类对象合成一步完成。

格式:

new 父类/接口(){

重复父类/接口中的方法

}

public classDemo {public static voidmain(String[] args) {newThread() {//重写run方法

@Overridepublic voidrun() {for (int i = 0; i < 20; i++) {

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

}

}

}.start();

}

}

//接口匿名类,第一种方法

Runnable r = newRunnable() {

@Overridepublic voidrun() {for (int i = 0; i < 20; i++) {

System.out.println(Thread.currentThread().getName()+ "黑马");

}

}

};newThread(r).start();//接口匿名类,第二种,更简便

new Thread(newRunnable() {

@Overridepublic voidrun() {for (int i = 0; i < 20; i++) {

System.out.println(Thread.currentThread().getName()+ "你好");

}

}

}).start();

关于线程安全,有时间在更新吧~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值