黑马程序员_多线程

---------------------- <a href="http://www.itheima.com"target="blank">ASP.Net+Unity开发</a>、<a href="http://www.itheima.com"target="blank">.Net培训</a>、期待与您交流! ----------------------

多线程(概述)

进程是一个正在执行中的程序,每一个进程执行都有一个执行顺序,该顺序就是一个执行路径或者叫控制单元

线程就是进程中的一个独立的控制单元。线程在控制着进行的执行(一个进程中至少有一个线程)。

《Java—jvm启动的时候会有一个进程叫java.exe该进程当中至少有一个线程在负责java程序的执行,而且这个线程运行的代码存在于main方法中》该线程称之为主线程。

扩展:其实更细节说明jvm,jvm启动不止一个线程,还有负责垃圾回收机制的线程

多线程的一个特性:随机性。谁抢到谁执行,至于执行多长时间,cpu说的算。

 

创建线程的第一种方式:继承Thread类。

1、定义类继承Thread。

2、复写Thread类中的run方法。目的:将自定义代码存储在run方法。让线程运行。

3、调用线程的start方法,该方法两个作用:启动线程,调用run方法。

 

创建线程的第二种方式:实现Runnable接口。

1、定义类实现Runnable接口

2、覆盖Runnable接口中的run方法。将线程要运行的代码存放在该run方法中。

3、通过Thread类建立线程对象。

4、将Runnable接口的子类对象作为实际参数传递给Thread类的构造函数。

5、调用Thread类的start方法开启线程并调用Runnable接口子类的run方法。

 

//需求:银行有一个金库,有2个储户分别存300元,每次存一百,存三次

//目的:该程序是否有安全问题,如果有如何解决?

class sankDemo

{

         publicstatic void main(String[] args)

         {

                   cusc = new cus();

                   Threadt1 = new Thread(c);

                   Threadt2 = new Thread(c);

                   t1.start();

                   t2.start();

         }

}

class sank

{

         privateint sum;

         publicvoid add(int n)

         {

                   sum= sum +n;

                   System.out.println("sum="+sum);

         }

}

class cus implements Runnable

{

         privatesank b = new sank();

         publicvoid run()                

         {

                   for(intx = 0;x<3;x++)

                   {

                            b.add(100);

                   }

         }

}

 

 

 

同步代码块格式:

synchronized(唯一对象)

         {

                   需要被同步的代码;

         }

 

同步的前提:

1、必须要有两个或者两个以上的线程。

2、必须是多个线程使用同一个锁。

 

同步函数的锁是this

静态同步函数的锁是Class对象

 

单例设计模式之懒汉式:

class Single

         {

                   privateSingle(){}

                   privatestatic Single single = null;

                   public  staticSingle getInstance()

                            {

                                     if(single==null)

                                               {//避免每次都判断锁,只有当对象为null的情况下才判断

                                                        synchronized(Single.class)

                                                        {

                                                                 if(single==null)/*如果一个线程跑到第一个if后死了,另一个线程进来创建了对象释放了锁,然后那个线程醒了,进来后还要判断*/

                                                                 single=new Single();

                                                        }

                                               }

                                     returnsingle;

                            }

         }

 

wait() notify() notifyAll()都是用在同步中,因为要对持有监视器(锁)的线程操作,所以使用在同步中,因只有同步中有锁。

为什么这些操作线程的方法要定义在object类中呢?

答:因为这些方法在操作同步中的线程时,都必须要标示他们所操作线程只有的锁。

只有同一个锁上的被等待线程可以被同一个锁上的线程被notify唤醒。同时不可以对不同所中的线程进行唤醒。

也就是说等待和唤醒必须是同一个锁。而锁可以是任意对象,所以可以被任意对象调用的方法定义在object中。

 

Notify():往往唤醒线程池中的第一个,所以可能唤醒本方导致数据错乱全部等待。可以用notifyall全部唤醒。

当出现多个生产者消费者同时要做这件事情的时候要用循环while和notifyall,(通用1.while判断标记,2.把对方唤醒)当只有一个生产者和消费者时可以用if

 

停止线程:Stop方法已过时,如果停止线程呢:只有一种,run()方法结束

原理:开启多线程运行,运行代码通常是循环。只要控制循环,皆可以让run方法结束即线程结束。

 

守护线程:线程对象.setDaemon(true);将该线程标记为守护线程或用户线程。

当正在运行的线程都是守护线程时,Java虚拟机退出,程序结束。

 

多线程(Join方法)

特点:当A线程执行到了B线程的.join()方法时,那么A线程就会等待B线程都执行完A才会执行。它可以用于临时加入线程执行

 

---------------------- <a href="http://www.itheima.com"target="blank">ASP.Net+Unity开发</a>、<a href="http://www.itheima.com"target="blank">.Net培训</a>、期待与您交流! ----------------------

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值