黑马程序员 java编程之多线程

来源:互联网 发布:php nginx 返回截断 编辑:程序博客网 时间:2024/04/30 11:51
---------------------- ASP.Net+Unity开发、.Net培训、期待与您交流! ----------------------

         

在学习到多线程的时候老师先给我们提出另外一个名词,叫做进程, 进程是指正在执行的程序。在windows中,我们可以从任务管理器中看到进程这个词语,发现在进程列表中列出了很多计算机当前运行着的程序。


         而线程就是程序内部的一条执行线索。一个进程中可以包含一个或者多个线程。多线程的概念就就像是计算机能同运行很多个程序一样。其实一个CPU在某一时刻只能处理一件事情,但是为什么我们感觉计算机中的程序能同时运行呢,比如说我们在用聊QQ的时候还能听歌还能在word文档中编辑文件还能干其他别的很多事情呢,这些程序不是同时在运行的吗?我个人的理解是,在一个宏观的概念里,我们感觉起来这个程序确实是同时运行,但是事实是这样的:计算机在运行过程中会根据要运行的程序,会划分出很多的时间片,每个时间片的时间很短, 在这个时间片里cpu在执行程序A,其他的程序处于等待状态,到了下一个时间片后cpu开始执行程序B,其他程序也都处于等待运行状态(包括程序A),就这样多个程序被轮流执行,由于计算机的执行速度很快,每个时间片时间又很短,所以 是感觉计算是在同时运行了多个程序。


   假如计算机中运行了很多个程序的时候,而计算机的硬件配置有不是很好,就会发现程序运行的时候会卡,这个就说明了 计算机中的程序不是同时执行的。

   创建线程有两种方式:
   (1)--继承Thread类,在子类中覆盖run方法,run方法中的代码是线程的执行代码,通过调用从Thread继承来 的start方法启动线程;
public class Demo extends Thread
{
public void run(){
   System.out.println("demo1");
}
}
主函数:
public static void main(String[] args)
{
Demo demo = new Demo();
demo.start();
System.out.println("main");
}
这样程序中就有了两个线程。
   (2)--实现Runnable接口,在实现接口的类中覆盖run方法,同样run方法中的代码是线程要执行的代码,通过以实现Runnable接口的类的实例对象为参数的构造函数创建Thread类的实例对象,启动线程是通过Thread类的实例对象调用start方法。
public class Demo implements Runnable
{
public void run(){
   System.out.println("demo1");
}
}
主函数:
public static void main(String[] args)
{
Demo demo = new Demo();
Thread t = new Thread(demo);
t.start();
System.out.println("main");
}
这样同实现Runnable,然后覆盖run方法后,也能创建出一个线程。


实现Runnable接口的好处:
1,将线程的任务从线程的子类中分离出来,进行了单独的封装。按照面向对象的思想将任务的封装成对象。
2,避免了java单继承的局限性。


所以,创建线程的第二种方式较为常用。


多线程安全问题产生的原因:
一个线程在执行多条语句时,并运算同一个数据时,在执行过程中有其他线程参与进来并操作了这个数据,因此产生了错误的数据。


线程同步:当多个线程运行相同代码时,当其中一个线程运行到共同代码块的一部分时,cpu不去执行其他线程中可能影响当前线程中的下一句代码执行结果的代码块,必须等下一句代码执行完才去执行其他线程有关代码块。简单来说就是,程序中不能有多个线程同时在这两句代码之间执行。

    同步代码块:synchronized(object){
//代码
}

同步函数:把函数设置成同步的如public synchronized void sop(){} ,这样再在run方法中调用同步函数就能达到线程同步的效果,注意同步函数的监视器是this既对象本身。所以             要想让同步代码块与同步函数之间达到同步就把
同步代码块改为</FONT>synchronized(this){}当然要在同一个类中定义。

死锁问题:两个或者以上线程锁定监视器时构成死循环造成的。


class DeadLock implements Runnable
{Boolean flag=true;//flag用于判断线程进入哪段执行代码
String lock1=new String("");
String lock2=new String("");
if(flag)
{
synchronized(lock1)
{
synchronized(lock2)
{
}
}
}
else{
synchronized(lock2)
{
synchronized(lock1)
{
}
}
}
 
}
如果两个线程分别运行其中的两个代码块,并且使用的是相同的一对控制器lock1与lock2那么这两个线程就可能造成死锁


同步死锁:通常只要将同步进行嵌套,就可以看到现象。同步函数中有同步代码块,同步代码块中还有同步函数。


线程间通信:思路:多个线程在操作同一个资源,但是操作的动作却不一样。
1:将资源封装成对象。
2:将线程执行的任务(任务其实就是run方法。)也封装成对象。


等待唤醒机制:涉及的方法:
wait:将同步中的线程处于冻结状态。释放了执行权,释放了资格。同时将线程对象存储到线程池中。
notify:唤醒线程池中某一个等待线程。

notifyAll:唤醒的是线程池中的所有线程。


----------------------ASP.Net+Unity开发、.Net培训、期待与您交流! ----------------------详细请查看:www.itheima.com

0 0
原创粉丝点击