线程的实现方式

线程的实现方式:
 a.继承Thread类,重写run方法
   Thread类:
         所属包:java.lang;
          构造方法:
              public Thread();
              public Thread(String name);
              public Thread(Runnable target);
              public Thread(Runnable target,String name);
          静态方法:
              static Thread currentThread();//获取当前线程
              static void sleep(long millis);//让线程休息millis毫秒
          成员变量:
            private Runnable target;
         成员方法:
              void start();//启动线程(只能调用一次,不能调用多次)
              void run(){};//线程启动后执行run方法
              String getName();//获取线程名字
              void setName(String name);//设置线程名字

public class MyThread extends Thread{
    @Override
    public void run() {
        super.run();
        System.out.println("继承Thread类实现run方法");
    }
    public static void main(String[] args) {
        MyThread th = new MyThread();
        th.start();
    }
     b.实现Runnable接口,实现run方法
       Runnable接口:
              public abstract void run()

public class MyRunnable implements Runnable{
        @Override
        public void run() {
            System.out.println("实现runnable类接口");
        }
        public static void main(String[] args) {
            MyRunnable runnable = new MyRunnable();
            //创建线程
            Thread th = new Thread(runnable);
            th.start();
        }

     c.使用匿名内部类创建Callable方法,重写call方法

Callable<T>接口:
         T call();

Callable<String> c = new Callable<String>() {
            @Override
            public String call() throws Exception {
                //call方法中的代码是某个子线程执行的
                System.out.println(Thread.currentThread().getName());
                Thread.sleep(500);
                return "test callable";
            }
        };
        //创建一个固定线程池对象
        ExecutorService es = Executors.newFixedThreadPool(2);

        Future<String> future = es.submit(c);
        //这行代码是主线程执行的
        String result = future.get();
        System.out.println(result);
        //关闭线程池
        es.shutdown();

     d.创建线程池

Executors类:
          static ExecutorService newFiexdThredadPool(int nThread);    

  ExecutorService接口:
          void execute(Runnable r);//执行任务
          <T> Future<T> submit(Callable<T> c);
          Future<?> submit(Runnable r);
          void shutdown();//关闭线程池

    Future<T>接口
         T get();//必须等子线程把任务执行完成,return以后才可以获取返回的结果。


 Runnable r = new Runnable() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName());
                try {
                    Thread.sleep(10000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };
        //创建一个固定线程池对象
        ExecutorService es = Executors.newFixedThreadPool(2);
        //执行任务
        es.execute(r);
        es.execute(r);
        es.execute(r);
        //关闭线程池
        es.shutdown();
      执行任务使用Runnable的方式和Thread的方式区别:建议使用Runnable
           a.可以避免Java单继承的局限性
           b.解耦合,任务和线程分离,提高代码的健壮性
           c.线程池里面,只能传入Runnable或者Callable类型的对象,不用new Thread
     线程池的使用好处:   
          1.提高响应速度。预先创建好了线程,只等任务过来执行。
          2.降低资源消耗。线程池中的线程,执行完任务后,又返回到线程池中,下一个任务到来后               可以继续使用该线程。
         3.提高线程的可管理性。一个线程大约需要消耗1M的空间,线程池可以设置最大线程的数                  量。
 
      线程安全:
         线程安全的前提:多个线程访问同一资源,有可能产生线程安全问题
      解决线程安全问题的三种方式:
          synchronized代码块:
                  语法:
                      synchronized(锁对象){
                          //有可能发生线程安全问题的代码
                      }
  
       synchronized方法:synchronized关键字写在返回值之前
            静态:static修饰的方法。锁对象:当前类的反射对象。  Class 对象名 = 类名.class;
            非静态:非static修饰的方法。锁对象:this
  
     Lock接口:
        void lock();
        void unlock();
         常用的实现类:ReentrantLock
              构造方法:
                  public ReentrantLock();
      synchronized:执行完大括号中的代码后,会自动释放锁。
  
      synchronized代码块或者方法中发生异常后会不会释放锁对象:会释放锁对象
      Lock:必须手动的调用unlock方法才能释放锁。
      Lock锁,发生异常后不会自动释放,所以建议把手动释放锁的代码写在finally块中
  
      线程的状态:
          NEW:新建状态。一个线程创建以后,启动之前,就处于该状态。

Thread t=new Thread();
        State s = t.getState();
        System.out.println(s);//NEW新建状态
          TERMINATED:消亡状态。线程执行完任务后,处于该状态。
          RUNNABLE:可运行状态。线程正在整型任务,就处于该状态
          BLOCKED:阻塞状态。获取synchronized锁对象失败,处于该状态

Runnable r=new Runnable() {
            @Override
            public void run() {
                synchronized (this) {
                    for(;;);
                }
            }
        };
        Thread t1 = new Thread(r);
        t1.start();
        Thread t2 = new Thread(r);
        t2.start();
        Thread.sleep(100);//100毫秒保证两个子线程已经启动,并开始执行代码了
        //获取并打印线程的状态
        System.out.println(t1.getState());
        System.out.println(t2.getState());
        //获取了锁对象开始执行for循环的线程处于RUNNABLE状态
        //没有获取锁对象的线程处于BLOCKED状态。
          WAITING:无限等待状态。获取Lock锁对象失败,就处于该状态

Lock lock=new ReentrantLock();
        Runnable r=new Runnable() {
            @Override
            public void run() {
                lock.lock();
                for(;;);
            }
        };
        Thread t1=new Thread(r);
        t1.start();
        
        Thread t2=new Thread(r);
        t2.start();
        //100毫秒内保证两个子线程开始执行任务
        Thread.sleep(100);
        System.out.println(t1.getState());
        System.out.println(t2.getState());
        //获取了锁对象开始执行for循环的线程处于RUNNABLE状态
        //没有获取Lock锁对象的线程处于WAITING状态。
          TIMED_WAITING:计时等待状态。执行sleep方法,就处于该状态。
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值