Java多线程理解

王朝学院·作者佚名  2016-08-27  
宽屏版  字体: 小 | 中 | 大 | 超大  

一、理论概念

进程与线程

进程(PRocess)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位。

线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位.线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),但是它可与同属一个进程的其他的线程共享进程所拥有的全部资源.

进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响,而线程只是一个进程中的不同执行路径。线程有自己的堆栈和局部变量,但线程之间没有单独的地址空间,一个线程死掉就等于整个进程死掉,所以多进程的程序要比多线程的程序健壮,但在进程切换时,耗费资源较大,效率要差一些。但对于一些要求同时进行并且又要共享某些变量的并发操作,只能用线程,不能用进程。

二、线程的java实现

目前实现java线程有2种方式,继承Thread类和实现Runnable接口,重写run方法。

1、实现Runnable接口

实现 Runnable的接口的好处是实现变量的共享,多个线程使用同一个Runable对象,如上代码块中的成员变量j:

packagesrc;/***

*@authorShawn Wang

**/publicclassMyThreadimplementsRunnable {privateintj = 100;

@Overridepublicvoidrun() {while(true) {if(j > 0) {

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

+ j--);

}else{

break;

}

}

}publicstaticvoidmain(String[] args) {

MyThread mt=newMyThread();

Thread thread1=newThread(mt);

Thread thread2=newThread(mt);

Thread thread3=newThread(mt);

thread1.start();

thread2.start();

thread3.start();

}

}

View Code

输出结果:

Thread-1-- num:100Thread-3-- num:98Thread-2-- num:99Thread-2-- num:95Thread-3-- num:96Thread-1-- num:97Thread-1-- num:92Thread-1-- num:91Thread-3-- num:93Thread-3-- num:89Thread-3-- num:88Thread-2-- num:94Thread-2-- num:86Thread-2-- num:85Thread-2-- num:84Thread-3-- num:87Thread-3-- num:82Thread-1-- num:90Thread-1-- num:80Thread-3-- num:81Thread-3-- num:78Thread-3-- num:77Thread-3-- num:76Thread-3-- num:75Thread-3-- num:74Thread-2-- num:83Thread-2-- num:72Thread-2-- num:71Thread-2-- num:70Thread-3-- num:73Thread-1-- num:79Thread-3-- num:68Thread-3-- num:66Thread-3-- num:65Thread-2-- num:69Thread-2-- num:63Thread-2-- num:62Thread-2-- num:61Thread-2-- num:60Thread-2-- num:59Thread-2-- num:58Thread-2-- num:57Thread-2-- num:56Thread-2-- num:55Thread-2-- num:54Thread-2-- num:53Thread-2-- num:52Thread-3-- num:64Thread-1-- num:67Thread-3-- num:50Thread-2-- num:51Thread-3-- num:48Thread-1-- num:49Thread-3-- num:46Thread-2-- num:47Thread-3-- num:44Thread-1-- num:45Thread-3-- num:42Thread-2-- num:43Thread-3-- num:40Thread-1-- num:41Thread-3-- num:38Thread-2-- num:39Thread-3-- num:36Thread-1-- num:37Thread-3-- num:34Thread-2-- num:35Thread-3-- num:32Thread-1-- num:33Thread-3-- num:30Thread-2-- num:31Thread-3-- num:28Thread-1-- num:29Thread-3-- num:26Thread-2-- num:27Thread-3-- num:24Thread-1-- num:25Thread-3-- num:22Thread-2-- num:23Thread-3-- num:20Thread-1-- num:21Thread-3-- num:18Thread-2-- num:19Thread-3-- num:16Thread-1-- num:17Thread-3-- num:14Thread-2-- num:15Thread-3-- num:12Thread-1-- num:13Thread-3-- num:10Thread-2-- num:11Thread-3-- num:8Thread-1-- num:9Thread-3-- num:6Thread-2-- num:7Thread-3-- num:4Thread-1-- num:5Thread-3-- num:2Thread-2-- num:3Thread-1-- num:1

result

2、继承Thread类

packagesrc;publicclassThreadClientextendsThread {publicThreadClient(String name) {super(name);

}

@Overridepublicvoidrun() {//TODO Auto-generated method stubfor(inti = 0; i <= 10; i++) {

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

}

}publicstaticvoidmain(String[] args) {

ThreadClient thread1=newThreadClient("thread1");

ThreadClient thread2=newThreadClient("thread1");

ThreadClient thread3=newThreadClient("thread1");

thread1.start();

thread2.start();

thread3.start();

}

}

View Code

输出结果

thread1:0thread1:1thread1:0thread1:1thread1:0thread1:1thread1:2thread1:3thread1:4thread1:5thread1:6thread1:2thread1:2thread1:3thread1:4thread1:3thread1:4thread1:5thread1:6thread1:7thread1:7thread1:8thread1:9thread1:10thread1:5thread1:6thread1:7thread1:8thread1:9thread1:8thread1:9thread1:10thread1:10

result

疑问:

为什么要重写 run方法?

run方法时存储线程所要运行的代码,不能在直接调用run方法,需要通过start方法来调用。

三、线程同步

场景:如果线程进行了sleep 操作时,其他线程对共享变量做了改变,会造成数据不同步问题。

packagesrc;/***

*@authorShawn Wang

**/publicclassMyThreadimplementsRunnable {privateintj = 100;

@Overridepublicvoidrun() {while(true) {if(j > 0) {try{

Thread.sleep(1000);//当前线程休眠1秒}catch(Exception e) {

e.printStackTrace();

}

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

+ j--);

}else{

break;

}

}

}publicstaticvoidmain(String[] args) {

MyThread mt=newMyThread();

Thread thread1=newThread(mt);

Thread thread2=newThread(mt);

Thread thread3=newThread(mt);

thread1.start();

thread2.start();

thread3.start();

}

}

View Code

输出结果:

Thread-1-- num:100Thread-2-- num:99Thread-3-- num:98Thread-1-- num:97Thread-3-- num:95Thread-2-- num:96Thread-1-- num:94Thread-2-- num:92Thread-3-- num:93Thread-3-- num:91Thread-2-- num:90Thread-1-- num:90Thread-3-- num:89Thread-2-- num:88Thread-1-- num:87Thread-3-- num:86Thread-2-- num:85Thread-1-- num:85Thread-3-- num:84Thread-2-- num:83Thread-1-- num:82Thread-3-- num:81Thread-1-- num:80Thread-2-- num:80Thread-3-- num:79Thread-2-- num:77Thread-1-- num:78Thread-3-- num:76Thread-2-- num:75Thread-1-- num:74Thread-2-- num:73Thread-3-- num:71Thread-1-- num:72Thread-2-- num:70Thread-1-- num:69Thread-3-- num:69Thread-2-- num:68Thread-3-- num:66Thread-1-- num:67Thread-2-- num:65Thread-1-- num:64Thread-3-- num:64Thread-2-- num:63Thread-1-- num:62Thread-3-- num:61Thread-2-- num:60Thread-3-- num:58Thread-1-- num:59Thread-2-- num:57Thread-1-- num:56Thread-3-- num:56Thread-2-- num:55Thread-1-- num:54Thread-3-- num:54Thread-2-- num:53Thread-3-- num:52Thread-1-- num:52Thread-3-- num:51Thread-2-- num:50Thread-1-- num:51Thread-3-- num:49Thread-1-- num:48Thread-2-- num:48Thread-3-- num:47Thread-1-- num:46Thread-2-- num:45Thread-1-- num:44Thread-2-- num:42Thread-3-- num:43Thread-3-- num:40Thread-1-- num:39Thread-2-- num:41Thread-2-- num:38Thread-3-- num:37Thread-1-- num:38Thread-1-- num:36Thread-2-- num:35Thread-3-- num:36Thread-1-- num:34Thread-2-- num:33Thread-3-- num:33Thread-1-- num:32Thread-3-- num:30Thread-2-- num:31Thread-1-- num:29Thread-3-- num:29Thread-2-- num:29Thread-3-- num:28Thread-1-- num:28Thread-2-- num:28Thread-1-- num:27Thread-2-- num:26Thread-3-- num:27Thread-1-- num:25Thread-2-- num:24Thread-3-- num:24Thread-1-- num:23Thread-3-- num:22Thread-2-- num:22Thread-1-- num:21Thread-3-- num:20Thread-2-- num:20Thread-1-- num:19Thread-3-- num:18Thread-2-- num:17Thread-3-- num:16Thread-1-- num:15Thread-2-- num:14Thread-2-- num:13Thread-3-- num:12Thread-1-- num:13Thread-2-- num:11Thread-1-- num:10Thread-3-- num:10Thread-2-- num:9Thread-1-- num:7Thread-3-- num:8Thread-2-- num:6Thread-3-- num:5Thread-1-- num:5Thread-2-- num:4Thread-3-- num:3Thread-1-- num:2Thread-2-- num:1Thread-1-- num:0Thread-3-- num:-1

result

出现了负数。

解决加上同步锁synchronized

同步代码块的格式:

synchronized(对象){

需要被同步的代码;

}

packagesrc;/***

*@authorShawn Wang

**/publicclassMyThreadimplementsRunnable {privateintj = 100;

@Overridepublicvoidrun() {while(true) {synchronized(this) {if(j > 0) {try{

Thread.sleep(1000);//当前线程休眠1秒}catch(Exception e) {

e.printStackTrace();

}

System.out.println(Thread.currentThread().getName()+ "-- num:" + j--);

}else{

break;

}

}

}

}publicstaticvoidmain(String[] args) {

MyThread mt=newMyThread();

Thread thread1=newThread(mt);

Thread thread2=newThread(mt);

Thread thread3=newThread(mt);

thread1.start();

thread2.start();

thread3.start();

}

}

View Code

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
© 2005- 王朝网络 版权所有