Java中的线程

一个java应用程序至少有两个线程, 一个是主线程负责main方法代码的执行,一个是垃圾回收器线程,负责了回收垃圾。

多线程的好处:
1. 解决了一个进程能同时执行多个任务的问题。
2. 提高了资源的利用率。

多线程 的弊端:
1. 增加cpu的负担。
2. 降低了一个进程中线程的执行概率。
3. 引发了线程安全 问题。
4. 出现了死锁现象。

 

创建线程的方式:
方式一:
1. 自定义一个类继承Thread类。
2. 重写Thread类的run方法 , 把自定义线程的任务代码写在run方法中
3. 创建Thread的子类对象,并且调用start方法开启线程。
注意: 一个线程一旦开启,那么线程就会执行run方法中的代码,run方法千万不能直接调用,直接调用run方法就相当调用了一个普通的方法而已,并没有开启新的线程。

public class Demo1 extends Thread {
    @Override  //把自定义线程的任务代码写在run方法中。
    public void run() {
        for(int i  = 0 ; i < 100 ; i++){
            System.out.println("自定义线程:"+i);
        }
    }
    public static void main(String[] args) {
        //创建了自定义的线程对象。
        Demo1 d = new Demo1();
        //调用start方法启动线程
        d.start();
        
        for(int i  = 0 ; i < 100 ; i++){
            System.out.println("main线程:"+i);
        }
    }    
}

方式二:
1. 自定义一个类实现Runnable接口。
2. 实现Runnable接口 的run方法,把自定义线程的任务定义在run方法上。
3. 创建Runnable实现类对象。
4. 创建Thread类 的对象,并且把Runnable实现类的对象作为实参传递。
5. 调用Thread对象 的start方法开启一个线程。

public class Demo implements Runnable{
    @Override
    public void run() {
        for(int i = 0 ; i < 100 ; i++){
            System.out.println(Thread.currentThread().getName()+":"+i);
        }
    }
    public static void main(String[] args) {
        //创建Runnable实现类的对象
        Demo d = new Demo();
        //创建Thread类的对象, 把Runnable实现类对象作为实参传递。
        Thread thread = new Thread(d,"狗娃"); //调用thread对象的start方法开启线程。
        thread.start();
    } 
}

推荐使用: 第二种。 实现Runable接口的。
原因: 因为java单继承 ,多实现的。

线程的生命周期:

 

线程安全问题:

可以使用同步代码块去解决。

格式:
synchronized(锁对象){
  //需要被同步的代码
}

同步代码块要注意的事项:

1. 锁对象可以是任意的一个对象。
2. 一个线程在同步代码块中sleep了,并不会释放锁对象。
3. 如果不存在着线程安全问题,不要使用同步代码块,因为会降低效率。
4. 锁对象必须是多线程共享的一个资源,否则锁不住。

/*需求: 一个银行账户5000块,两夫妻一个拿着 存折,一个拿着卡,开始取钱比赛,每次只能取一千块,要求不准出现线程安全问题。*/

class BankThread extends Thread{
    static int count = 5000;
   static Object o=new Object(); 
    public BankThread(String name){
        super(name);
    }
    @Override  //
    public synchronized  void run() {
        while(true){
            synchronized (o) {                
                if(count>0){
                    System.out.println(Thread.currentThread().getName()+"取走了1000块,还剩余"+(count-1000)+"元");
                    count= count - 1000;
                }else{
                    System.out.println("取光了...");
                    break;
                }
            }
        }
    }
}
public class Demo {
    public static void main(String[] args) {
        //创建两个线程对象
        BankThread thread1 = new BankThread("老公");
        BankThread thread2 = new BankThread("老婆");
        //调用start方法开启线程取钱
        thread1.start();
        thread2.start();
    }
}

 使用创建线程的方式二解决线程安全问题:

class SaleTicket implements Runnable{
    //这里不需要创建为静态变量,因为只需要实例化一个SaleTicket 对象
    int  num = 50; // 票数
    @Override
    public void run() {
        while(true){
            synchronized ("锁") {
                if(num>0){
                    System.out.println(Thread.currentThread().getName()+"售出了第"+ num+"号票");
                    num--;
                }else{
                    System.out.println("售罄了..");
                    break;
                }    
            }
        }        
    }
}


public class Demo {
    public static void main(String[] args) {
        //创建了一个Runnable实现类的对象
        SaleTicket saleTicket = new SaleTicket();
        //创建三个线程对象模拟三个窗口
        Thread thread1 = new Thread(saleTicket,"窗口1");
        Thread thread2 = new Thread(saleTicket,"窗口2");
        Thread thread3 = new Thread(saleTicket,"窗口3");
        //开启线程售票
        thread1.start();
        thread2.start();
        thread3.start();
    }
}

 

 

 

 

 

posted on 2018-05-17 21:12  琪琪伤感  阅读(221)  评论(0编辑  收藏  举报