java-线程

java-线程

线程:是一个程序里面不同的执行路径
进程:一个class文件,一个exe文件,静态的概念,进程的执行指的是进程里面的主线程,main方法执行了,实际上都是线程在执行
        同一个时间点上,一个cpu只能支持一个线程在执行

两种方式创建线程:1.继承thread(只能是单继承较狭隘)

                          

                         2.实现runnerable

一些常用到的方法属性:
sleep:休眠(并不释放锁)
join:合并线程(相当于方法调用)
yield:让出小会儿给别人执行

线程的优先级

Object.wait():(让正在访问此代码块的线程等待一下,让别的线程继续运行)调用此方法时,必须锁定该对象
Object.notify():(叫醒正在访问此代码块的单个线程)

Object.notifyAll():(叫醒正在访问此代码块的所有线程)

synchronized:线程同步(锁定当前内容,同一时间只有一个线程访问它):
      

 

死锁: 是指两个或两个以上的进程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生 了死锁,这些永远在互相等待的进程称为死锁进程。 由于资源占用是互斥的,当某个进程提出申请资源后,使得有关进程在无外力协助下,永远分配不到必需的资源而无法继续运行,这就产生了一种特殊现象死锁

        如果线程A锁住了记录1并等待记录2,而线程B锁住了记录2并等待记录1,这样两个线程就发生了死锁现象

复制代码
package thread;

/**
 * 
 * @description
 *                    死锁的例子
 * @package name      
 *                    thread.DeadLock.java
 * @author            
 *                    lj
 * @since              
 *                    2012-4-8下午10:44:04
 */
public class DeadLock implements Runnable{
    int flag;
    static Object o1 = new Object();//注意是静态的,那样才是属于类独有的,不是属于对象的
    static Object o2 = new Object();
    
    public void run() {
        System.out.println("flag:" + flag);
        if(flag == 1) {
            synchronized (o1) {
                try{
                    Thread.sleep(500);
                }catch(Exception e){
                    e.printStackTrace();
                }
                
                synchronized (o2) {
                    System.out.println("  看到了此输出说明flag为1的线程完全执行了");
                }
            }
        }else{
            synchronized (o2) {
                try{
                    Thread.sleep(500);
                }catch(Exception e){
                    e.printStackTrace();
                }
                
                synchronized (o1) {
                    System.out.println(" 看到了此输出说明flag为2的线程完全执行了");
                }
            }
            
        }
        
    }
    
    public static void main(String[] args) {
        DeadLock dl1 = new DeadLock();
        dl1.flag = 1;
        DeadLock dl2 = new DeadLock();
        dl2.flag = 2;
        
        Thread t1 = new Thread(dl1);
        t1.start();
        Thread t2 = new Thread(dl2);
        t2.start();
    }
}
复制代码

System.out.println(" 看到了此输出说明flag为1/2的线程完全执行了"); 始终没有执行,没有输出,出现了死锁

 

 

生产者消费者问题:

复制代码
  1 package thread;
  2 
  3 /**
  4  * 
  5  * @description
  6  *                    生产者消费者问题    
  7  * @package name      
  8  *                    thread.ProducerConsumer.java
  9  * @author            
 10  *                    lj
 11  * @since              
 12  *                    2012-4-8下午09:52:23
 13  */
 14 public class ProducerConsumer {
 15     public static void main(String[] args) {
 16         Basket bk = new Basket();
 17         Producer p = new Producer(bk);
 18         Consumer c = new Consumer(bk);
 19         new Thread(p).start();
 20         new Thread(c).start();
 21     }
 22 }
 23 /**
 24  * 
 25  * @description
 26  *                    馒头     
 27  * @package name      
 28  *                    thread.ProducerConsumer.java
 29  * @author            
 30  *                    lj
 31  * @since              
 32  *                    2012-4-8下午09:52:46
 33  */
 34 class Bun {
 35     int id;
 36     public Bun(int id) {
 37         this.id = id;
 38     }
 39     
 40     public String toString() {
 41         return "第" + (id+1) + "个馒头";
 42     }
 43 }
 44 /**
 45  * 
 46  * @description
 47  *                    篓子    
 48  * @package name      
 49  *                    thread.ProducerConsumer.java
 50  * @author            
 51  *                    lj
 52  * @since              
 53  *                    2012-4-8下午09:53:00
 54  */
 55 class Basket {
 56     Bun[] buns = new Bun[5];
 57     int index;
 58     /**
 59      * 生产馒头
 60      * @author        
 61      *                  lj  
 62      * @since    
 63      *                  2012-4-8下午09:54:28
 64      * @param b void
 65      *                  返回
 66 */
 67     public synchronized void add(Bun b) {//同步是防止生产者放了馒头,但是因为某些异常,index没有来得及加加,但是实际上框子的馒头个数可能超过了10,你还想放
 68         while(index == buns.length) {
 69             try {
 70                 this.wait();
 71             } catch (InterruptedException e) {
 72                 // TODO Auto-generated catch block
 73                 e.printStackTrace();
 74                 System.out.println("生产馒头时候的等待异常");
 75             }
 76         }
 77         this.notify();//不写表明已经是满的了,但不叫醒消费者,就放在那里
 78         buns[index] = b;
 79         index++;
 80     }
 81     /**
 82      * 消费馒头
 83      * @author        
 84      *                  lj  
 85      * @since    
 86      *                  2012-4-8下午09:54:50
 87      * @return Bun
 88      *                  返回
 89 */
 90     public synchronized Bun get() {//同步是防止消费者拿了馒头,但是因为某些异常,indent没有来得及减减,但是实际上框子里可能没有馒头了,但是你还想拿
 91         while(index == 0) {
 92             try {
 93                 this.wait();
 94             } catch (InterruptedException e) {
 95                 // TODO Auto-generated catch block
 96                 e.printStackTrace();
 97                 System.out.println("拿馒头时候的等待异常");
 98             }
 99         }
100         //用if出现了异常,程序会跳出if继续执行后面的语句,而while不会
101         /*if(index == 0) {
102             try {
103                 this.wait();
104             } catch (InterruptedException e) {
105                 // TODO Auto-generated catch block
106                 e.printStackTrace();
107             }
108         }*/
109         this.notify();//假设index=6,不写表明已经拿完了,但不叫醒生产者,总是空着
110         index--;//前面的index指针已经加加了,但是我没有那个位置装馒头,所以取出馒头的索引得往下减(类比栈内存)
111         return buns[index];
112     }
113 }
114 /**
115  * 
116  * @description
117  *                    生产者    
118  * @package name      
119  *                    thread.ProducerConsumer.java
120  * @author            
121  *                    lj
122  * @since              
123  *                    2012-4-8下午09:53:16
124  */
125 class Producer implements Runnable{
126     Basket bk;
127     public Producer(Basket bk) {
128         this.bk = bk;
129     }
130     @Override
131     public void run() {
132         for(int i = 0; i < 10; i++) {
133             Bun b = new Bun(i);
134             bk.add(b);
135             System.out.println("生产了" + b);
136             try {
137                 Thread.sleep((int)Math.random()*1000);
138             } catch (InterruptedException e) {
139                 // TODO Auto-generated catch block
140                 e.printStackTrace();
141                 System.out.println("生产异常");
142             }
143         }
144     }
145     
146 }
147 /**
148  * 
149  * @description
150  *                    消费者       
151  * @package name      
152  *                    thread.ProducerConsumer.java
153  * @author            
154  *                    lj
155  * @since              
156  *                    2012-4-8下午09:53:40
157  */
158 class Consumer implements Runnable {
159     Basket bk;
160     public Consumer(Basket bk) {
161         this.bk = bk;
162     }
163     @Override
164     public void run() {
165         for(int i = 0; i < 10; i++) {
166             Bun b = bk.get();
167             try {
168                 Thread.sleep((int)Math.random()*1000);
169             } catch (InterruptedException e) {
170                 // TODO Auto-generated catch block
171                 e.printStackTrace();
172                 System.out.println("消费异常");
173             }
174             System.out.println("拿走了" + b);
175         }
176     }
177     
178 }
复制代码

 

反对使用stop(),是因为它不安全。它会解除由线程获取的所有锁定,当在一个线程对象上调用stop()方法时,这个线程对象所运行的线程就会立即停止,假如一个线程正在执行:synchronized void { x = 3; y = 4;} 由于方法是同步的,多个线程访问时总能保证x,y被同时赋值,而如果一个线程正在执行到x = 3;时,被调用了 stop()方法,即使在同步块中,它也干脆地stop了,这样就产生了不完整的残废数据。而多线程编程中最最基础的条件要保证数据的完整性,所以请忘记线程的stop方法,以后我们再也不要说“停止线程”了。而且如果对象处于一种不连贯状态,那么其他线程能在那种状态下检查和修改它们。结果 很难检查出真正的问题所在。

suspend()方法容易发生死锁。调用suspend()的时候,目标线程会停下来,但却仍然持有在这之前获得的锁定。此 时,其他任何线程都不能访问锁定的资源,除非被"挂起"的线程恢复运行。对任何线程来说,如果它们想恢复目标线程,同时又试图使用任何一个锁定的资源,就 会造成死锁。所以不应该使用suspend(),而应在自己的Thread类中置入一个标志,指出线程应该活动还是挂起。若标志指出线程应该挂起,便用 wait()命其进入等待状态。若标志指出线程应当恢复,则用一个notify()重新启动线程

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值