浅析Java中线程的实现方式总结

一.继承Thread类重写run()方法

编写一个类继承Thread,重写run()方法

public class SubThread extends Thread{
	@Override
	public void run() {
		//获取当前线程,执行当前代码的线程
		Thread t = Thread.currentThread();
		//获取线程的名称
		String name = t.getName();
		//System.out.println(name+" hello Thread");
		
		for (int i = 0; i < 100; i++) {
			System.out.println(name+"--"+i);
			try {
				Thread.sleep(100);//单位是毫秒
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}

调用线程对象的start()方法启动线程

public static void main(String[] args) {
		//创建一个子线程
		Thread t = new SubThread();
		t.start();
		
		//如果直接调用run方法,run方法中的代码是由主线程执行的
		//t.run();
	}

 二.使用匿名内部类的方式创建Thread类型的对象

public static void main(String[] args) {
		//创建线程对象
		Thread t = new SubThread();
		t.setName("a");
		t.start();
		
		//使用匿名内部类的方式创建Thread类型的对象
		Thread t2 = new Thread("b") {
			@Override
			public void run() {
				//获取线程的名称
				String name = Thread.currentThread().getName();
				
				//定义变量,保存总和
				int sum = 0;
				for (int i = 1; i <= 200; i++) {
					sum+=i;
				}
				System.out.println(name+":"+sum);
			}
		};
		//启动线程
		t2.start();

	}

三.实现Runnable接口,重写run()方法

        Runnable接口的方式和继承Thread类的方式:建议使用Runnable方式
             a.线程和任务分离,解耦合,提高代码的健壮性。
             b.避免了Java单继承的局限性
             c.线程池里面,只能传入Runnable或者Callable类型的对象,不用new Thread
        Runnable接口:
            public abstract void run();

public static void main(String[] args) {
		//创建一个Runnable类型的对象
		Runnable r = new Runnable() {
			@Override
			public void run() {
				String name = Thread.currentThread().getName();
				System.out.println(name);
			}
		};
		
		//把Runnable类型的对象,赋值给Thread类的成员变量target
		Thread t = new Thread(r,"线程1");
		t.start();
	}
public static void main(String[] args) {
		//创建一个Runnable类型的对象
		Runnable r = new Runnable() {
			@Override
			public void run() {
				//获取线程的名称
				String name = Thread.currentThread().getName();
				for (int i = 1; i <= 100; i++) {
					System.out.println(name+"--"+i);
				}
			}
		};
		
		
		new Thread(r).start();
		new Thread(r).start();
	}

四. 实现Callable接口,重写call()方法

Runnable是执行工作的独立任务,但是不返回任何值。如果我们希望任务完成之后有返回值,可以实现Callable接口

该方法效率较低,因为在获取线程的执行结果的时候,当前线程受阻塞。但是可以拿到线程的返回结果

/*
 * 实现Callable接口,重写call方法,利用FutureTask可以获取线程返回值
 *
 */
public class CallableTest implements Callable {
    @Override
    public Object call() {
        System.out.println("run===" + Thread.currentThread().getId());
        return "success" + Thread.currentThread().getId();
    }

    public static void main(String[] args) throws ExecutionException, InterruptedException {

        CallableTest callableTest = new CallableTest();
        for (int i = 0; i < 10; i++) {
            FutureTask<Object> future = new FutureTask<Object>(callableTest);
            Thread thread = new Thread(future);
            thread.start();
            // 获取返回值
            future.get();
        }
    }
}

线程池:
      1.提高响应速度。预先创建好了线程,只等任务过来执行。
      2.降低资源消耗。线程池中的线程,执行完任务后,又返回到线程池中,下一个任务到来后可以继续使用该线程。
      3.提高线程的可管理性。一个线程大约需要消耗1M的空间,线程池可以设置最大线程的数量。
      Executors类:
          static ExecutorService newFiexdThredadPool(int nThread);    
      ExecutorService接口:
          void execute(Runnable r);//执行任务
          <T> Future<T> submit(Callable<T> c);
          Future<?> submit(Runnable r);
          void shutdown();//关闭线程池

注意线程安全:

      线程安全产生的前提:多个线程访问同一资源(数据) 
      整个的操作不是原子操作:
          1.使用synchronized代码块
              语法:
                  synchronized(锁对象){//可以是任意类型的对象
                      //写有可能发生线程安全问题的代码
                  } 
          2.使用synchronized方法
              静态synchronized方法:在static和返回值之间加synchronized关键字
              非静态synchronized方法:在返回值之前加synchronized关键字 
          synchronized代码块和方法:代码执行完毕后,自动释放锁            
          3.使用Lock锁
              Lock接口:
                  void lock();//上锁
                  void unlock();//开锁 
                  常用实现类:ReentrantLock
                      构造方法:
                          public ReentrantLock();

要想达到线程安全的效果,必须是同一个锁对象
      synchronized方法:
          静态:当前类的反射对象,获取当前类的反射对象
              Class c = 类名.class;//获取一个类的反射对象 
          非静态:锁对象是this

 Java中线程的状态:
          NEW:新建状态。创建了一个线程,启动之前处于该状态
          RUNNABLE:可运行状态。线程正在执行任务(run方法中的代码),就处于该状态
          BLOCKED:阻塞状态。获取synchronized锁对象失败,就处于该状态
          WAITING:无限等待状态。获取Lock锁对象失败,就处于该状态
          TIMED_WAITING:计时等待状态。线程正在执行sleep方法的时候,就处于该状态
          TERMINATED:消亡状态。线程执行完任务后,就处于该状态

  • 6
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值