Java中有一个比较重要的知识点是多线程,废话就不说了,直接进入多线程的知识点。对多线程我们需要了解和知道一下的知识点:多线程的实现,多线程的安全性,多线程的线程通信,守护线程和线程的优先级等知识点。
首先,我想写点我对多线程的一点认识,其中说的语言不会很官方,但是我相信里面绝对没有坑,不会把大家带到歧途上去的。首先多线程的出现是为了更好的利用计算机的资源,提高程序的响应速度。多线程的运行由操作系统来控制,多核和单核的cpu执行同一个多线程程序的过程可能会不同,在单核中多线程程序只能在单核之间切换执行,在一个时间点上只能有一个线程处于运行的状态。但是在多核的cpu上我们会看到,同一个时间点上,多线程的程序的几个线程可能会运行在cpu的不同核上面,也就是说在同一个时间点上有多个线程同时在运行。大家这里注意点啊,平时我们说的多线程的同时运行很多的时候指的是多个线程在cpu上做快速的切换,如果是单核的cpu这个时候只是多个线程在做快速的切换,在任意一个时间点上,只有一个线程在运行,但是对于多核的cpu可能会是上面单核的情况也可能会是这样的状态:多个线程运行在不同的核心上,这个时候同一个时间点上会有多个线程在运行。
接下来我们看下关于多线程的实现,有二种方法,继承Thread 类和实现Runnable 接口,由于Java是单继承的,所以在平时的开发中我们使用的最多是实现Runnable接口来做的,具体怎么实现,自己去网上找啊。
接下来我们看看多线程的线程安全性的一点问题。为什么会出现线程的安全性那?出现这个问题的原因就是我们在多个线程之间共享和操作和同一个数据,如果不操作同一个数据,各个线程各自操作自己独立的数据,那么就不会有这样的问题出现,既然要共享和操作同一个数据,由于一个线程在执行的时候,会失去cpu的执行资格,等它再获取cpu的执行资格的时候会接着上次执行的继续执行,但是在它没有执行的这段时间会有其他的线程会操作共享的数据,这样可能就会出现错误,下面对这个做一个小的例子程序给大家看下,很简单,有经验的就不用看了。
private int total_number = 100;
@Override
public void run() {
// TODO Auto-generated method stub
while(total_number>0)
{
try {
Thread.currentThread().sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(total_number--);
}
}
加上 sleep()只是让问题凸显出现,如果不加这个程序本身也是有问题的,会在某次运行的时候出现,但是程序员在自己电脑上运行的时候可能半天不会出现,这段本身就是有问题的。打印的结果中出现0,-1,-2,为什么会出现真的问题那,我们可以这样看,当我们假设线程一运行到判断和total_number>0 的时候,total_number这个时候是1,刚进去这个时候线程一sleep了,这个时候线程二进来了它也会进行判断,这个时候total_number 还是1,它判断之后也进入sleep ,这个时候我们可以假设线程一sleep的时间到了,并且获得了cpu的执行资格,这个时候我们会看到线程一会接下来执行打印的操作,当然就打印出了-1的错误数据。
出现了错误的数据,我们应该怎么办啊,Java为我们提供的解决办法是使用锁synchronized,使用锁之后我们可以让一个线程使用的的资源在没有完全释放的时候,其他线程无法进行访问,上面的代码可以改成: