关于线程和进程的学习,我们已经进行了很多遍了,但是对于这两者的区别还是不知道怎么去理解.所以做一下总结吧。
### 关于进程和线程的区别
**a.地址空间和其它资源**:进程间相互独立,同一进程的各线程间共享。某进程内的线程在其它进程不可见。
**b.通信**:进程间通信IPC,线程间可以直接读写进程数据段(如全局变量)来进行通信——需要进程同步和互斥手段的辅助,以保证数据的一致性。
**c.调度和切换**:线程上下文切换比进程上下文切换要快得多。
**d.在多线程OS中,进程不是一个可执行的实体。**
一个简单的例子,就是进程就好像一个工厂,这个工厂做产品需要一些资源.而线程就好像工厂中的工人,这些工人之间的资源时共享的.
### 线程的实现
线程的实现由两种方法,一种是继承分别为继承Thread类和实现Runable接口。
下面是两段代码分别实现这两个方法。
### 一.使用Runable接口
~~~
public class MyThread {
public static void main(String[] args)
{
Runner r = new Runner();
// r.run();//使用此处我们可以看到两个方法分别执行
Thread t=new Thread(r);
t.start();//使用多线程,我们可以发现我们的两个方法是同时执行的
for(int i = 0;i<100;i++)
{
System.out.println("Main Thread:"+i);
}
}
}
class Runner implements Runnable
{
public void run()
{
for(int i=0;i<100;i++)
{ System.out.println("runner:"+i);
}
}
}
~~~
### 二.继承Thread类
~~~
public class MyThread {
public static void main(String[] args)
{
Runner r = new Runner();
r.start();
for(int i = 0;i<100;i++)
{
System.out.println("Main Thread:"+i);
}
}
}
class Runner extends Thread
{
public void run()
{
for(int i=0;i<100;i++)
{ System.out.println("runner:"+i);
}
}
}
~~~
使用多线程得到的输出结果:
![](https://box.kancloud.cn/2016-03-23_56f1fee6c958e.jpg)
使用Runnable阶段创建线程时,需要首先编写一个实现Runnable接口的类.然后实例化该类的对象,这样就建立了
Runnable对象,接下来使用构造方法创建Thread实例.最后使用Start()方法启动线程.
当一个类继承了Thread后,就可以在该类中覆盖run()方法,将实现线程功能的代码写入run()中.然后调用Thread的Start()方法.
看过之后我们会发现两个方法是这么的相似.如果我们查API,我们就会明白实质上Thread类就是实现了Runnable接口,其中的Run方法就是对Runnable接口中Run()方法的具体实现。
### 生命周期
线程的生命周期,包括出生、就绪、运行、等待、休眠、阻塞和死亡七种状态。
下面的一张图展示了这几个状态的联系。其中也展示了线程的一些操作
![](https://box.kancloud.cn/2016-03-23_56f1fee6de886.jpg)
### 线程的同步
在多线程中会发生两个线程抢占资源的的问题。为了解决这个问题,java提供了线程同步机制。
我们通过一个实例来理解一下这个机制。这张图实现了一个简单的买门票的过程.门票的张数不能是负值.
~~~
public class MyThread {
public static void main(String[] args)
{
ThreadSafeTest t = new ThreadSafeTest();
//实例化四个线程实例
Thread tA=new Thread(t);
Thread tB=new Thread(t);
Thread tC=new Thread(t);
Thread tD=new Thread(t);
//启动这四个线程实例
tA.start();
tB.start();
tC.start();
tD.start();
}
}
class ThreadSafeTest implements Runnable
{
int num=10;
public void run()
{
while(true){
if(num>0){
try
{
Thread.sleep(100);
}
catch(Exception e)
{
e.printStackTrace();
}
System.out.println("门票还有" + num + "张" );
num=num-1;
}
}
}
}
~~~
执行结果为:
![](https://box.kancloud.cn/2016-03-23_56f1fee705494.jpg)
这个过程中我们可以看到出现了负值,这是由于同时创建了四个线程,这个四个线程同时执行run方法,而且这四个线程同是取得数值,同是递减.导致剩余门票的张数出现上面的情况.
然后,我们给run方法加入同步机制.
~~~
public class MyThread {
public static void main(String[] args)
{
ThreadSafeTest t = new ThreadSafeTest();
//实例化四个线程实例
Thread tA=new Thread(t);
Thread tB=new Thread(t);
Thread tC=new Thread(t);
Thread tD=new Thread(t);
//启动这四个线程实例
tA.start();
tB.start();
tC.start();
tD.start();
}
}
class ThreadSafeTest implements Runnable
{
int num=10;
public void run()
{
while(true)
{
synchronized("")//该关键字的使用就保证了同步
{
if(num>0){
try
{
Thread.sleep(100);
}
catch(Exception e)
{
e.printStackTrace();
}
System.out.println("门票还有" + num + "张" );
num=num-1;
}
}
}
}
}
~~~
![](https://box.kancloud.cn/2016-03-23_56f1fee713e45.jpg)
### 总结
学习了多线程编程就像进入了一个全新的领域,它与以往的编程思想不同,现在很多的程序语言都以支持和扩展多线程,作为初学者应该及时转变我们的编程思路,是我们的变成进入一个多线程编程的思维方式.同时多线程也是一种复杂的机制,完全理解它我们还要更深入的去研究