码迷,mamicode.com
首页 > 编程语言 > 详细

黑马程序员------多线程(二)

时间:2015-06-15 11:03:01      阅读:192      评论:0      收藏:0      [点我收藏+]

标签:

黑马程序员------多线程(二)

1.1 同步代码块:Java对多线程的安全问题提供了专业的解决方式

格式:

synchronized(对象)
{
需要被同步的代码(共享数据)

 

}

对象如同锁。持有锁的线程可以在同步中执行。
没有持有锁的线程即使获取cpu的执行权,也进不去,因为没有获取锁。

火车上的卫生间---经典。

同步的前提:
1,必须要有两个或者两个以上的线程。
2,必须是多个线程使用同一个锁。

必须保证同步中只能有一个线程在运行。


好处:解决了多线程的安全问题。

弊端:多个线程需要判断锁,较为消耗资源

示例1:

 1 class Ticket implements Runnable
 2 {
 3     private  int tick = 1000;
 4     Object obj = new Object();
 5     public void run()
 6     {
 7         while(true)
 8         {
 9             synchronized(obj)
10             {
11                 if(tick>0)
12                 {
13                     //try{Thread.sleep(10);}catch(Exception e){}
14                     System.out.println(Thread.currentThread().getName()+"....sale : "+ tick--);
15                 }
16             }
17         }
18     }
19 }
20 
21 
22 class  TicketDemo2
23 {
24     public static void main(String[] args) 
25     {
26 
27         Ticket t = new Ticket();
28 
29         Thread t1 = new Thread(t);
30         Thread t2 = new Thread(t);
31         Thread t3 = new Thread(t);
32         Thread t4 = new Thread(t);
33         t1.start();
34         t2.start();
35         t3.start();
36         t4.start();
37 
38 
39     }
40 }

 

 

1.2同步函数

同步函数格式:

public synchronized void show()

{

}

如何找问题?

1.明确哪些代码是多线程运行代码

2.明确共享数据

3.明确多线程运行代码中哪些语句是操作共享数据的?

同步函数的锁是 this。函数需要被对象调用,那么函数都有一个所属对象引用。

想让线程停一下  

Thread.sleep(10);

如果同步函数被静态修饰后,使用的锁是 class

synchronized (对象名.class)

 

 

1.3 死锁:

同步中嵌套同步,可能会发生,该怎么解决

是由于 两个线程相互等待 对方已被锁定的资源

循环等待条件:第一个线程等待其它线程,后者又在等待第一个线程。

避免死锁的一个通用的经验法则是:当几个线程都要访问共享资源A、B、C时,

保证使每个线程都按照同样的顺序去访问它们,比如都先访问A,在访问B和C。

 

 

1.4 线程间通信:多个线程在操作同一个资源,但是操作的动作不同。

1.是不是两个或两个以上的线程。解决办法 两个线程都要被同步。
2.是不是同一个锁。解决办法 找同一个对象作为锁。

等待唤醒机制。

wait后,线程就会存在线程池中,notify后就会将线程池中的线程唤醒。
notifyAll();唤醒线程池中所有的线程。
实现方法 :

给资源加个标记 flag

synchronized(r)
{
while(r.flag)//多个生产者和消费者 if(r.flag)//一个生产者和消费者
r.wait();
代码
r.flag=true;
r.notify();
r.notifyAll();
}

上面三种方法都使用在同步中,因为要对持有监视器(锁)的线程操作。所以要使用在同步中,因为只有同步才具有锁。

为什么这些操作线程的方法要定义在object类中呢?
因为这些方法在操作同步中线程的是偶,都必须要表示它们所操作线程只有的锁。只有同一个锁上的被等待线程,可以被
同一个锁上的notify唤醒,不可以对不同锁中的线程进行唤醒。

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

 


1.5 Lock接口 多生产者和消费者 JDK1.5版本升级版(示例2) 
Lock 替代了synchronized
Condition 替代了 Object监视器方法

好处:将同步synchronized 替换成了 Lock
将object中的wait notify notifyAll 替换成了 Condition对象
该对象可以Lock锁进行获取。一个锁可以对应多个Condition对象
注意:释放锁的工作一定要执行

示例2

 1 private Lock lock=new ReentrantLock();
 2 private Condition condition =lock.newCondition();
 3 
 4 public void cet(String name ) throws 
 5 {
 6    lock.lock();
 7    try
 8    {
 9       while(flag)
10            contidition.await();
11        this.name=name+"--"+count++;
12 
13        sop(Thread.currentThread().getName()+"...生产者..."+this.name)
14        flag=true15         condition.signalAll();
16 
17     }
18     finally
19     {
20        lock.unlock();
21          
22    }
23 }

 

 

1.6 停止线程、守护线程、Join方法:

停止线程:

run方法结束,就会停止线程,开启多线程运行,运行代码通常是循环结构。只要控制住循环,就可以让线程结束。

方法:改变标记。


特殊情况,改变标记也不会停止的情况。

将处于冻结状态的线程恢复到运行状态。interrupt(); 中断线程。

守护线程:
SetDaemon将线程标记为守护线程或用户线程。在启动线程前调用 。当线程都为守护线程后,JVM退出。

Join方法:

t.join();抢过cpu执行权。

当A线程执行到了B线程的join方法时,A就会等待,等B线程执行完,A才会执行。Join可以用来临时加入线程执行。

优先级:
SetPriority(1-10)设置优先级。
Thread.MAX_PRIORITY 10
Thread.MIN_PRIORITY 1
Thread.NORM_PRIORITY 5

yield方法:暂停当前正在执行的线程对象,并执行其他线程。

开发中应用::保证以下三个代码同时运行。


示例3:

 1 new Thread()
 2 {
 3       for(int x=0;x<100;x++)
 4       {
 5          sop(Thread.currentThread().getName())
 6 
 7        }
 8 }.start();
 9 
10 
11  for(int x=0;x<100;x++)
12 {
13    sop(Thread.currentThread().getName())
14 
15 }
16 
17 Runnable r=new Runnable()
18 {
19    public voud run(){
20      for(int x=0;x<100;x++)
21      {
22       sop(Thread.currentThread().getName())
23 
24      }
25 
26     }
27 };
28 
29 new Thread(r).start();

 

 

 

黑马程序员------多线程(二)

标签:

原文地址:http://www.cnblogs.com/jiandonn/p/4576338.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!