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

java线程

时间:2015-05-24 21:47:30      阅读:140      评论:0      收藏:0      [点我收藏+]

标签:

线程安全出现的原因:1. 必须存在两个或者两个以上的线程。2. 多个线程共享着一个资源,而且操作资源的代码有多句。

案例:夫妻俩一起去银行取钱,一个拿着存折, 一个拿着卡,同时取钱。每次取100块,账户的总额是5000块,不准出现 线程安全问题。

技术分享
 1 class BankThread extends Thread{
 2     
 3     static    int count = 5000;   //账户的总额
 4     
 5     public BankThread(String name){
 6         super(name);
 7     }
 8     
 9     //非静态静态的同步函数 -----  锁对象this对象。
10     @Override
11     public  void run() {  
12         getMoney();
13     }
14     
15     //静态的同步函数 ---------->当前方法所属的类的class文件对象。
16     public synchronized static void getMoney(){
17         while(true){
18             if(count>0){
19                 System.out.println(Thread.currentThread().getName()+"取走了100块,还剩余"+(count-100)+"块");
20                 count-=100;
21             }else{
22                 System.out.println("取光了...");
23                 break;
24             }
25         }
26     }
27 }
28 
29 public class Demo1 {
30     
31     public static void main(String[] args) {
32         //创建线程对象
33         BankThread thread1 = new BankThread("老公");
34         BankThread thread2 = new BankThread("老婆");
35         //调用start方法启动线程。
36         thread1.start();
37         thread2.start();
38     }
39 }
View Code

案例:使用线程创建的Runnable方式模拟三个窗口卖票

技术分享
 1 class SaleTickets implements Runnable {
 2 
 3     int num = 50; // 非静态成员变量
 4 
 5     @Override
 6     public void run() { // this
 7         while (true) {
 8             synchronized ("锁") {
 9                 if (num > 0) {
10                     System.out.println(Thread.currentThread().getName()
11                             + "卖出了第" + num + "号票");
12                     num--;
13                 } else {
14                     System.out.println("售罄了...");
15                     break;
16                 }
17             }
18         }
19     }
20 }
21 
22 public class Demo2 {
23 
24     public static void main(String[] args) {
25         // 创建Runnable实现类的对象
26         SaleTickets saleTickets = new SaleTickets();
27         // 创建三个线程对象
28         Thread t1 = new Thread(saleTickets, "窗口1");
29         Thread t2 = new Thread(saleTickets, "窗口2");
30         Thread t3 = new Thread(saleTickets, "窗口3");
31         // 调用start方法开启线程
32         t1.start();
33         t2.start();
34         t3.start();
35     }
36 
37 }
View Code

守护线程(后台线程) : 当前一个java应用只剩下守护线程的时候,那么守护线程马上结束。

技术分享
 1 public class Demo3 extends Thread {
 2     
 3     public Demo3(String name){
 4         super(name);
 5     }
 6     
 7     @Override
 8     public void run()  { // 子类抛出的异常类型必须要小于或者等于父类抛出 的异常类型。
 9         for(int i = 1 ;  i<100 ; i++){
10             System.out.println(this.getName()+"已经下载了:"+i+"%");
11             try {
12                 Thread.sleep(100);
13             } catch (InterruptedException e) {
14                 e.printStackTrace();
15             }
16         }
17         System.out.println("下载完毕,正在安装更新包!!!");
18     }
19     
20     public static void main(String[] args) {
21         //创建一个线程对象
22         Demo3 d = new Demo3("守护线程");
23         
24         d.setDaemon(true); //设置一个线程为守护线程。
25         //启动线程
26         d.start();
27         
28         for(int i = 0; i < 100 ; i++){
29             System.out.println(Thread.currentThread().getName()+":"+i);
30         }
31     }
32 }
View Code

join方法: 线程让步。需求:模拟小时候打酱油。

技术分享
 1 class Mother extends Thread{
 2     
 3     @Override
 4     public void run() {
 5         System.out.println("妈妈洗菜...");
 6         System.out.println("妈妈切菜...");
 7         System.out.println("妈妈发现没有酱油了...");
 8         //通知儿子去打酱油
 9         Son s = new Son();
10         s.start();
11         try {
12             s.join();   //  join 加入  : 如果当前线程执行了join方法,那么当前线程就会让步给新加入的线程先完成任务,然后当前线程才继续的执行自己的任务。
13             
14         } catch (InterruptedException e) {
15             e.printStackTrace();
16         } 
17         System.out.println("妈妈炒菜...");
18         System.out.println("全家一起吃饭...");
19     }    
20 }
21 
22 //儿子线程
23 class Son extends Thread{
24     
25     @Override
26     public void run() {
27         try {
28             System.out.println("儿子下楼梯");
29             Thread.sleep(1000);
30             System.out.println("儿子一直往前走...");
31             System.out.println("儿子买到了酱油...");
32             System.out.println("儿子跑回来...");
33             Thread.sleep(1000);
34             System.out.println("儿子把酱油给老妈..");
35         } catch (InterruptedException e) {
36             e.printStackTrace();
37         }    
38     }
39 }
40 
41 public class Demo4 {
42     
43     public static void main(String[] args) {
44         Mother m =  new Mother();
45         m.start();
46     }
47 }
View Code

线程的通讯: 当一个线程完成了一个任务的时候,要通知另外一个线程去处理其他 的事情。

wait() 执行了wait方法的线程,会让该线程进入以锁对象建立的线程池中等待。
notify() 如果一个线程执行了notify方法,该线程会唤醒以锁对象建立的线程池中等待线程中的一个.
notifyAll() 把所有的线程都唤醒。

案例:生产者与消费者,生产一个、消费一个。

技术分享
  1 package day0524;
  2 
  3 //产品类
  4 class Product{
  5     
  6     String name;
  7     
  8     int price;
  9     
 10     boolean flag ;  //产品是否生成完毕的标识   false为还没有生成完毕, true 生成完毕了.
 11     
 12 }
 13 
 14 //生产者类
 15 class Producer extends Thread{
 16     
 17     //维护一个产品
 18     Product p;
 19     
 20     public Producer(Product p){
 21         this.p = p;
 22     }
 23     
 24     @Override
 25     public void run() {
 26         int i = 0; 
 27         while(true){
 28             synchronized (p) {    
 29                 if(p.flag==false){
 30                     if(i%2==0){
 31                         p.name = "摩托车";
 32                         p.price= 4000;
 33                     }else{
 34                         p.name = "自行车";
 35                         p.price = 300;
 36                     }
 37                     System.out.println("生产了"+ p.name+" 价格:"+ p.price);
 38                     i++;
 39                     //生成完毕 --- 改标识
 40                     p.flag = true; 
 41                     //唤醒消费者去消费
 42                     p.notifyAll();;
 43                 }else{
 44                     //如果产品已经生产完毕,应该等待消费者先消费
 45                     try {
 46                         p.wait();
 47                     } catch (InterruptedException e) {
 48                         e.printStackTrace();
 49                     }
 50                 }
 51             }
 52         }
 53     }
 54 }
 55 
 56 //消费者
 57 class Customer extends Thread{
 58     
 59     //产品
 60     Product p;
 61     
 62     public Customer(Product p){
 63         this.p = p;
 64     }
 65     
 66     @Override
 67     public void run() {
 68         while(true){
 69             synchronized (p) {
 70                 if(p.flag==true){
 71                     System.out.println("消费者消费了:"+ p.name+" 价格:"+ p.price);
 72                     //改标识
 73                     p.flag = false;
 74                     p.notifyAll();
 75                 }else{
 76                     //如果产品已经被消费完毕,应该唤醒生产者去生成
 77                     try {
 78                         p.wait();
 79                     } catch (InterruptedException e) {
 80                         e.printStackTrace();
 81                     }
 82                 }
 83             }
 84         }
 85     }
 86 }
 87 
 88 public class Demo5 {
 89     
 90     public static void main(String[] args) {
 91         //创建一个产品对象
 92         Product p = new Product();
 93         //创建线程对象
 94         Producer producer = new Producer(p);
 95         Customer customer = new Customer(p);
 96         //启动线程
 97         producer.start();
 98         customer.start();
 99         
100     }
101 }
View Code

停止线程:如果我们停止的是一个等待状态下的线程,那么需要配合interrupt方法去使用。

技术分享
 1 package day0524;
 2 
 3 public class Demo6 extends Thread {
 4 
 5     boolean flag = true;
 6 
 7     public Demo6(String name) {
 8         super(name);
 9     }
10 
11     @Override
12     public synchronized void run() {
13         int i = 0;
14         while (flag) {
15             try {
16                 this.wait(); // 狗娃等待...
17             } catch (InterruptedException e) {
18                 System.out.println("接收到了一个InterruptedException.."); // 狗娃
19             }
20             System.out.println(Thread.currentThread().getName() + ":" + i);
21             i++;
22         }
23     }
24 
25     public static void main(String[] args) {
26         // 创建线程对象
27         Demo6 d = new Demo6("狗娃");
28         d.start();
29 
30         // 当主线程的i到80的时候,停止狗娃线程。
31         for (int i = 0; i < 100; i++) {
32             if (i == 80) {
33                 d.flag = false; // interrupt() 无法停止一个线程,
34                 d.interrupt(); // 强制清除一个线程的wait、 sleep状态。 可以指定清除那个线程。
35 
36             }
37             System.out.println(Thread.currentThread().getName() + ":" + i);
38         }
39     }
40 
41 }
View Code

java同步机制解决了线程安全问题,但是同时也引发了死锁现象。

技术分享
 1 package day0524;
 2 
 3 class DeadLockThread extends Thread {
 4 
 5     public DeadLockThread(String name) {
 6         super(name);
 7     }
 8 
 9     @Override
10     public void run() {
11         if ("张三".equals(this.getName())) {
12             synchronized ("遥控器") {
13                 System.out.println(this.getName() + "取走了遥控器,准备取电池");
14                 synchronized ("电池") {
15                     System.out.println(this.getName() + "取到了电池,开着空调爽歪歪的吹着 !!");
16                 }
17             }
18 
19         } else if ("李四".equals(this.getName())) {
20             synchronized ("电池") {
21                 System.out.println(this.getName() + "取走了电池,准备取取遥控器");
22                 synchronized ("遥控器") {
23                     System.out.println(this.getName() + "取走了遥控器,开着空调爽歪歪的吹着 !!");
24                 }
25             }
26         }
27     }
28 }
29 
30 public class Demo7 {
31 
32     public static void main(String[] args) {
33         // 创建了线程对象
34         DeadLockThread thread1 = new DeadLockThread("张三");
35         DeadLockThread thread2 = new DeadLockThread("李四");
36         thread1.setPriority(10);
37         thread2.setPriority(1);
38         // 调用start方法启动线程
39         thread1.start();
40         thread2.start();
41     }
42 }
View Code

 

java线程

标签:

原文地址:http://www.cnblogs.com/syliuchang/p/4526369.html

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