java线程

定义线程

1、扩展java.lang.Thread类,实现run()方法,直接调用start()方法。

2、实现java.lang.Runnable接口,然后传递给Thread对象,调用start()方法。

线程模型

  每个线程有一个自己的栈。

线程的状态

1、线程睡眠是帮助所有线程获得运行机会的最好方法。sleep()是静态方法,只能控制当前正在运行的线程。

2、线程的让步是通过Thread.yield()来实现的。线程优先级为1~10之间的正整数。

  线程默认优先级是5,Thread类中有三个常量,定义线程优先级范围:
  static int MAX_PRIORITY 
            线程可以具有的最高优先级。 
  static int MIN_PRIORITY 
            线程可以具有的最低优先级。 
  static int NORM_PRIORITY 
            分配给线程的默认优先级。
实际中无法保证yield()达到让步目的,因为让步的线程还有可能被线程调度程序再次选中。(和Windows API Sleep一样)

线程同步

1、join()方法。  

  保证当前线程停止执行,直到该线程所加入的线程完成为止。join()方法可以设置超时时间间隔。

2、对象锁。

  Java中每个对象都有一个内置锁。当程序运行到非静态的synchronized同步方法上时,自动获得与正在执行代码类的当前实例(this实例)有关的锁。获得一个对象的锁也称为获取锁、锁定对象、在对象上锁定或在对象上同步。

  一个对象只有一个锁。所以,如果一个线程获得该锁,就没有其他线程可以获得锁。(这点相当别扭)

  只能同步方法,而不能同步变量和类。(极其恶心)

  在使用同步代码块时候,应该指定在哪个对象上同步,也就是说要获取哪个对象的锁。例如:

  

  可以同步静态方法。

  静态同步方法和非静态同步方法将永远不会彼此阻塞,因为静态方法锁定在Class对象上,非静态方法锁定在该类的对象上。

线程的交互

1、wait()、notify()、notifyAll()。

  注:必须从同步环境内调用wait()、notify()、notifyAll()方法。

    Notify是瞬间的事件,不是持续性事件。如果在wait()前调用了notify(),对wait没影响,也意味着wait将永远等待。

2、Thread.sleep()。线程休眠。

守护线程

  方法:setDaemon(true)

  注:JRE判断程序是否执行结束的标准是所有的前台执线程行完毕了,而不管后台线程的状态。

其它

  关键字:volatile

 

二.Java线程新特征之线程池

线程池

1、固定大小线程池

  import java.util.concurrent.Executors; 
  import java.util.concurrent.ExecutorService; 

  ExecutorService pool = Executors.newFixedThreadPool(2); 

  pool.execute(t1); 

  pool.shutdown(); 

2、单任务线程池

  ExecutorService pool = Executors.newSingleThreadExecutor();

3、可变尺寸线程池

  ExecutorService pool = Executors.newCachedThreadPool(); 

4、延迟连接池

  import java.util.concurrent.Executors; 
  import java.util.concurrent.ScheduledExecutorService; 
  import java.util.concurrent.TimeUnit; 

  ScheduledExecutorService pool = Executors.newScheduledThreadPool(2); 

  pool.schedule(t4, 10, TimeUnit.MILLISECONDS); 

5、单任务延迟连接池

  ScheduledExecutorService pool = Executors.newSingleThreadScheduledExecutor();

 

有返回值的线程

1、可返回值的任务必须实现Callable接口,类似的,无返回值的任务必须Runnable接口。

2、执行Callable任务后,可以获取一个Future的对象,在该对象上调用get就可以获取到Callable任务返回的Object了。

实例

 

/**
 * * Java线程:有返回值的线程
 * @author wb_qiuquan.ying
 */
@SuppressWarnings("unchecked")
public class Test {
 @SuppressWarnings("rawtypes")
 public static void main(String[] args) throws ExecutionException,InterruptedException {
  int sizeNum = 5;
  // 创建一个线程池
  ExecutorService pool = Executors.newFixedThreadPool(sizeNum);
  // 创建多个有返回值的任务
  List<Future> list = new ArrayList<Future>();
  for (int i = 0; i < sizeNum; i++) {
   // Callable c = new MyCallable(i + " ");也可以这样写,运行结果一样
   MyCallable c = new MyCallable(i + " ");
   // 执行任务并获取Future对象
   Future f = pool.submit(c);
   System.out.println("线程运行中此线程的值是:" + f.get().toString());
   list.add(f);
  }
  // 关闭线程池
  pool.shutdown();
  // 获取所有并发任务的运行结果
  System.out.println("");
  for (Future f : list) {
   // 从Future对象上获取任务的返回值,并输出到控制台
   System.out.println("关闭线程池后,各个线程的值:" + f.get().toString());
  }
  System.exit(0);
 }
}

class MyCallable implements Callable<Object> {
 private String taskNum;

 MyCallable(String taskNum) {
  this.taskNum = taskNum;
 }
 // call()方法
 public Object call() throws Exception {
  System.out.println(">>>" + taskNum + "call()方法任务启动");
  Date dateTmp1 = new Date();
  Thread.sleep(1000);
  Date dateTmp2 = new Date();
  long time = dateTmp2.getTime() - dateTmp1.getTime();
  System.out.println(">>>" + taskNum + "任务终止");
  return "线程" + taskNum + "返回运行的时间【" + time + "毫秒】";
 }
}

1、普通锁。

  import java.util.concurrent.locks.Lock; 
  import java.util.concurrent.locks.ReentrantLock; 

  Lock lock = new ReentrantLock(); 

  myLock.lock(); 

  myLock.unlock(); 

2、读写锁。

   Lock接口以及对象,使用它,很优雅的控制了竞争资源的安全访问,但是这种锁不区分读写,称这种锁为普通锁。为了提高性能,Java提供了读写锁,在读的地方使用读锁,在写的地方使用写锁,灵活控制,在一定程度上提高了程序的执行效率。

  import java.util.concurrent.locks.ReadWriteLock; 
  import java.util.concurrent.locks.ReentrantReadWriteLock; 

  ReadWriteLock lock = new ReentrantReadWriteLock(false);

  myLock.readLock().lock(); 

  myLock.readLock().unlock(); 

  myLock.writeLock().lock(); 

  myLock.writeLock().unlock(); 

信号量

1、信号量是解决消费者、生产者的最经典解决方案。

  import java.util.concurrent.Semaphore; 

  pool.getSp().acquire(x); 

  pool.getSp().release(x); 

阻塞队列

  阻塞队列的接口java.util.concurrent.BlockingQueue

  阻塞队列的概念是,一个指定长度的队列,如果队列满了,添加新元素的操作会被阻塞等待,直到有空位为止。同样,当队列为空时候,请求队列元素的操作同样会阻塞等待,直到有可用元素为止。

  import java.util.concurrent.BlockingDeque; 
  import java.util.concurrent.LinkedBlockingDeque; 

条件变量

  import java.util.concurrent.locks.Condition; 

  private Condition _save = lock.newCondition();

   _draw.await();

  _save.signalAll();

原子量

  所谓的原子量即操作变量的操作是“原子的”,该操作不可再分,因此是线程安全的。

  import java.util.concurrent.atomic.AtomicLong; 

  private static AtomicLong aLong = new AtomicLong(10000);

  aLong.addAndGet(x)

障碍器

  Java5中,添加了障碍器类,为了适应一种新的设计需求,比如一个大型的任务,常常需要分配好多子任务去执行,只有当所有子任务都执行完成时候,才能执行主任务,这时候,就可以选择障碍器了。

  import java.util.concurrent.CyclicBarrier; 

  CyclicBarrier cb = new CyclicBarrier(7, new MainTask()); 

  cb.await(); 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值