多线程的实现

多线程

在讲线程之前,我们应该先了解一下什么是进程?

 

进程:系统可以进行独立调配并且它是一个不可分割 独立单元

例如(我们手机或者电脑后台运行的软件,客户端等等,它们就是进程)

 

线程:线程是进程中一个独立的单元,线程有自己的堆栈和局部变量,但线程之间没有单独的地址空间

例如:(我们的电脑管家可以进行杀毒和清理垃圾,其中的杀毒和清理垃圾功能就可以看做事线程)

 

多线程:像上面所说的电脑管家,当我们同时执行清理垃圾和杀毒功能,虽然表面看起来是可以同步进行的,但实际不是同步进行的,只是每个线程在抢占CPU的执行权,这就是多线程。

多线程的意义:为了提高CPU的使用率,

线程之间都在抢占CPU的执行权,而且多线程的执行是随机的

 

要想实现多线程程序,需要开启进程,开启进程就需要创建系统资源,但是只有c/c++可以创建资源,所我们我们可以在底层利用c创建好的系统资源来实现

 

并发和并行的区别:

并发是指同一个时间点,物理逻辑上的

并行指的是同一个时间段。

让我们来看看多线程的实现:

首先我们需要创建一个子类去实现Thread类,并且要重写该类的run方法

package com.westos.Thread;
 
public class MyThread extends Thread{


/*public MyThread(String name) {
super(name);
}*/
 
public void run() {
for(int x=0;x<100;x++) {
System.out.println(getName()+":"+x);
}
}
 
}

 

创建一个实现类去实现多线程,这是给线程设置名字的两种方式:

package com.westos.Thread;
 
public class ThreadDome {
 
/**
 * @param args
 * 给线程设置名字的两种方式
 * 使用方式1时:可以不在MyThread类中添加无参构造,因为系统默认访问无参构造
 * 当你使用第二种方式时,就必须要添加有参构造了,否则就会报错
 */
public static void main(String[] args) {

//方式1:无参+setName()方法

//创建MyThread类对象

MyThread mt=new MyThread();
MyThread mt2=new MyThread();

//setName方法
mt.setName("迪丽热巴");
mt2.setName("井杰");

//开始运行
mt.start();
mt2.start();

//方式2:直接MyThread类的有参构造

/*//创建MyThread类对象
 
MyThread mt=new MyThread("迪丽热巴");
MyThread mt2=new MyThread("井杰");

//开始运行
mt.start();
mt2.start();
*/
}
}

 

线程的一些方法:

等待该线程终止

public final void join()throws InterruptedException等待该线程终止。

 

返回正在执行的线程:

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

 

 

package com.westos.Thread01;
 
public class ThreadJoin extends Thread{
 
public void run() {
for(int x=0;x<100;x++) {
System.out.println(getName()+":"+x);
}
}
}

 

package com.westos.Thread01;
 
public class ThreadDome {
public static void main(String[] args) {
//创建三个ThreadJoin类对象
ThreadJoin tj=new ThreadJoin();
ThreadJoin tj2=new ThreadJoin();
ThreadJoin tj3=new ThreadJoin();

//设置名字
tj.setName("刘备");
tj2.setName("张飞");
tj3.setName("关羽");

tj.start();
//public final void join()throws InterruptedException等待该线程终止。
try {
tj.join();
} catch (InterruptedException e) {
e.printStackTrace();
}

tj2.start();
tj3.start();
/*//public static Thread currentThread()返回对当前正在执行的线程对象的引用。
System.out.println(Thread.currentThread().getName());
运行的结果是:main(该方法返回的是正在执行的主线程,而tj和tj2是主线程的两个子线程)
*/
}
 
}

 

暂停线程:

public static void yield()暂停当前正在执行的线程对象,并执行其他线程

package com.westos.Thread02;
 
public class Threadyield extends Thread{
 
public void run() {
for(int x=0;x<100;x++) {
System.out.println(getName()+":"+x);
}
//public static void yield()暂停当前正在执行的线程对象,并执行其他线程。
Thread.yield();
}
}

 

 

package com.westos.Thread02;
 
public class YieldDome {
 
public static void main(String[] args) {
//创建Threadyield类对象
Threadyield ty=new Threadyield();
Threadyield ty2=new Threadyield();

//设置名字
ty.setName("蜘蛛侠");
ty2.setName("钢铁侠");

//开始运行
ty.start();
ty2.start();
}
}

 

守护线程:

public final void setDaemon(boolean on)将该线程标记为守护线程或用户线程

 

package com.westos.Thread03;
 
public class ThreadsetDaemon extends Thread{
 
public void run() {
for(int x=0;x<100;x++) {
System.out.println(getName()+":"+x);
}
}
}

 

 

package com.westos.Thread03;
 
/**
 * @author 杰哥
 *调用setDaemon方法时,必须有主线程一起启动,否则无法编译
 */
public class setDaemonDome {

public static void main(String[] args) {

//创建ThreadsetDaemon类对象
ThreadsetDaemon td=new ThreadsetDaemon();
ThreadsetDaemon td2=new ThreadsetDaemon();

td.setName("雅妃");
td2.setName("美杜莎");

//public final void setDaemon(boolean on)将该线程标记为守护线程或用户线程。
//当正在运行的线程都是守护线程时,Java 虚拟机退出。 
//该方法必须在启动线程前调用。 值为true时表示正常
 
td.setDaemon(true);
td2.setDaemon(true);

//启动线程
td.start();
td2.start();

Thread.currentThread().setName("萧炎");
for(int i=0;i<5;i++) {
System.out.println(Thread.currentThread().getName()+":"+i);
}

}
}

 

休眠:

public static void sleep(long millis) throws InterruptedException

在指定的毫秒数内让当前正在执行的线程休眠(暂停执行),

package com.westos.Thread03;
 
/**
 * @author 杰哥
 *调用setDaemon方法时,必须有主线程一起启动,否则无法编译
 */
public class setDaemonDome {

public static void main(String[] args) {

//创建ThreadsetDaemon类对象
ThreadsetDaemon td=new ThreadsetDaemon();
ThreadsetDaemon td2=new ThreadsetDaemon();

td.setName("雅妃");
td2.setName("美杜莎");

//public final void setDaemon(boolean on)将该线程标记为守护线程或用户线程。
//当正在运行的线程都是守护线程时,Java 虚拟机退出。 
//该方法必须在启动线程前调用。 值为true时表示正常
 
td.setDaemon(true);
td2.setDaemon(true);

//启动线程
td.start();
td2.start();

Thread.currentThread().setName("萧炎");
for(int i=0;i<5;i++) {
System.out.println(Thread.currentThread().getName()+":"+i);
}

}
}

 

package com.westos.Thread04;
 
public class ThreadsleepDome {
 
public static void main(String[] args) {

//创建对象
ThreadSleep ts=new ThreadSleep();
ThreadSleep ts2=new ThreadSleep();

ts.setName("张三");
ts2.setName("李四");

ts.start();
ts2.start();
}
}

 

stop()直接停止线程执行

interrupt():中断线程。

 

package com.westos.Thread05;
 
public class ThreadStopInterrupt extends Thread{
 
public void run() {
System.out.println("程序开始了...");
//睡眠10秒
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
// e.printStackTrace();
System.out.println("程序出现中断异常...");
}
System.out.println("程序结束了...");
}
}

 

package com.westos.Thread05;
 
public class StopInterruptDome {
 
public static void main(String[] args) {
ThreadStopInterrupt tsi=new ThreadStopInterrupt();

tsi.start();
try {
tsi.sleep(3000);
//表示停止
// tsi.stop();
//中断线程
tsi.interrupt();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

 

前面我们学习了多线程的实现,除了上面继承Thread类的这种方式呢,还有一种实现Runnable接口的方法,它也可以进行多线程的实现,但是其中的一些方法发生了改变,需要我们注意:

 

package com.westos.Runable;
 
 
/**
 * @author 杰哥
 *实现多线程的第二种方式:实现Runable接口
 */
public class RunnableDome implements Runnable{
 
public void run() {

for(int x=0;x<100;x++) {
//因为这是第二种方式,不是之前的继承Thread方式,所以不能直接调用getName方法
//Thread.currentThread()返回的是正在运行的线程
System.out.println(Thread.currentThread().getName()+":"+x);
}
}
}

 

package com.westos.Runable;
 
public class RunnableTest {
 
public static void main(String[] args) {

//创建RunableDome类对象
RunnableDome rd=new RunnableDome();

/**
 * Thread(Runnable target, String name) 分配新的 Thread 对象。
 * 这是Thread类有关Runnable接口的一种构造方法
 */
Thread t1=new Thread(rd,"杨过");
Thread t2=new Thread(rd,"小龙女");

t1.start();
t2.start();
}
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章