多线程

实现线程的两种方式

一:类名   extends Thread

  重写run方法

  类名  对象名 = new 类名();

  对象名.start(); 启动线程

二、类名   implements Runnable  (推荐使用)

  重写run方法

  类名  对象名 = new 类名();

  Thread 对象名1=new Thread(类名);

  对象名1.start(); 启动线程

  Thread 对象名2=new Thread(类名);

  对象名2.start(); 启动线程

 

线程的生命周期

 

 

线程不安全: 多个线程同时修改同一个数据

解决线程不安全的问题:  互斥性

 

1) 使用同步代码块(在同一个时间点,这个数据只能有一个线程在修改,其他线程只能等这个线程修改完,才能执行)   推荐使用 *

private Object obj = new Object();

   synchronized(锁对象){    //对象可以为this,建议自定义为obj

        //需要同步的代码(可能修改的代码)

  }

注意:

1)  锁对象, 可以是任意对象

2) 这个锁对象是多个线程共享的

 

同步: 解决线程不安全问题,  缺点:  效率低

2) 使用同步方法

使用同步方法:

  在这个方法声明上, snychronized这个关键字, 表示这个方法就是一个同步方法:

1) 非静态的同步方法, 锁对象就是非静态的同步方法所在类的对象:  this

    等同于:  snychronized(this){

  }

2) 静态的同步方法,  锁对象就是这个类的class对象

  获取某个类的class对象:  

  1) 类名.class

  2) 类的对象.getClass()

  3) Class.forName(“包名.类名”)

       很少使用:

3) JDK1.5的锁机制

private Lock lock = new ReentrantLock();

 lock.lock();

lock.unlock();

 

推荐: 使用同步代码块

1) 同步代码块比较灵活, 可以是方法的任意一部分,而同步方法就是整个方法都是同步

2) 同步代码块他的锁对象可以任意, 而同步方法锁对象,指定, 非静态的同步方法, 锁对象: this,  静态的同步方法,  这个类的class对象

 

线程池

代码:

public static void main(String[] args) {
		//10个任务, 同时执行, 创建10个线程
		
		//使用线程池,   固定数量的线程池
		ExecutorService service = Executors.newFixedThreadPool(5);
		
		for (int i = 0; i < 10; i++) {
			MyTask m = new MyTask();
			//从线程池,获取线程,执行我们的任务
			service.execute(m);
		}
		//关闭
		service.shutdown();
	}

  

public void run() {
		// 获取当前系统的时间毫秒值:
		// 1) new Date() 获取当前系统时间, 调用getTime() 获取毫秒值  底层调用 System类的  currentTimeMillis()
		// 2) 使用 System类的  currentTimeMillis()
		System.out.println(Thread.currentThread().getName()+"开始时间"+System.currentTimeMillis());
		try {
			Thread.sleep(500);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		System.out.println(Thread.currentThread().getName()+"结束时间"+System.currentTimeMillis());
	}

  

posted @ 2020-03-07 16:46  64Byte  阅读(149)  评论(0编辑  收藏  举报