Java线程

传统线程机制

线程的实现方法

java1.5之前实现多线程的方法有两种分别是:

1.Thread的子类,重新run方法

2.构造Thread的是传入runable子类,重写run方法

 

定时器Timer类

new Timer().schedule(new MyTimerTask(),2000);

class MyTimerTask extends TimerTask{

  public void run(){

    System.out.println("bombing");

    new Timer().schedule(new MyTimerTask(),2000);

  }

}

 

线程互斥与同步通信问题

线程安全问题可以用银行转账来解释

锁是上在代表要操作的资源的类的内部方法中,而不是线程代码中!

线程同步与通信,例题:

子线程循环10次,接着主线程循环100次,接着又回到子线程循环10次,接着再回到主线程又循环100次,如此循环50次,请写出程序。

这是道典型的线程同步与通信问题,

子线程循环10次,主线程循环100次,要同步,同步的方法放在同一个类中,高类聚低耦合的思想,子线程循环完了,在主线程循环,这个是通信问题代码如下:

 1 package com.lsf.test.thread;
 2 
 3 public class MyTraditionalThreadCommunitation {
 4     public static void main(String[] args) {
 5         final MyBusiness myBusiness = new MyBusiness();
 6         new Thread(
 7                 new Runnable() {
 8                     @Override
 9                     public void run() {
10                         for(int i=1;i<=50;i++){
11                             myBusiness.sub(i);
12                         }
13                     }
14                 }
15             ).start();
16         
17         for(int i=1;i<=50;i++){
18             myBusiness.main(i);
19         }
20     }
21 
22 }
23 
24 class MyBusiness{
25     private boolean isShowSub = true;
26     public synchronized void sub(int i){
27         while(!isShowSub){
28             try {
29                 this.wait();
30             } catch (InterruptedException e) {
31                 e.printStackTrace();
32             }
33         }
34         
35         for(int j=1;j<=10;j++){
36             System.out.println("子线程循环->"+ j +",循环了->"+i);
37         }
38         isShowSub = false;
39         this.notify();
40     }
41     
42     public synchronized void main(int i){
43         while(isShowSub){
44             try {
45                 this.wait();
46             } catch (InterruptedException e) {
47                 e.printStackTrace();
48             }
49         }
50         
51         for(int j=1;j<=10;j++){
52             System.out.println("主线程循环->"+ j +",循环了->"+i);
53         }
54         isShowSub=true;
55         this.notify();
56     }
57 }

 

ThreadLocal实现线程范围的共享变量

多个线程访问共享对象和数据的方式

1.如果每个线程执行的代码相同,可以使用同一个Runnable对象,这个Runnable对象中有那个共享数据,例如,卖票系统就可以这么做。

2.如果每个线程执行的代码不同,这时候需要用不同的Runnable对象,有如下两种方式来实现这些Runnable对象之间的数据共享。

a.将共享数据封装在两外一个对象中,然后将这个对象逐一传递给各个Runnable对象。每个线程对共享数据的操作方法也分配到那个对象身上去完成,这样容易实现针对该数据进行的各个操作的互斥和通信。

28、设计4个线程,其中两个线程每次对j增加1,另外两个线程对j每次减少1。写出程序。

Java5中的线程并发库

线程池

线程池的概念与Executors类的应用

  创建固定大小的线程池

  创建缓存线程池

  创建单一线程池

关闭线程池

线程池启动定时器

Callable&Future

 1      ExecutorService threadPool2 = Executors.newFixedThreadPool(10);
 2         CompletionService<Integer> completionService = new ExecutorCompletionService<Integer>(threadPool2);
 3         for(int i=1;i<=10;i++){
 4             final int seq = i;
 5             completionService.submit(new Callable<Integer>() {
 6                 @Override
 7                 public Integer call() throws Exception {
 8                     Thread.sleep(new Random().nextInt(5000));
 9                     return seq;
10                 }
11             });
12         }
13         
14         for(int i=0;i<10;i++){
15             try {
16                 System.out.println(completionService.take().get());
17             } catch (Exception e) {
18                 e.printStackTrace();
19             }
20         }

 Lock&Condition实现线程同步通信

Lock比传统线程模型中的synchronized方式更加面向对象,与生活中的锁类似,锁本身也应该是一个对象。两个线程执行的代码片段

新建锁对象

Lock lock = new ReentrantLock();

lock.lock();  //开启锁

lock.unlock();  //释放锁,这样做有个弊端  当前面的对象出现异常的时候,这个lock不会被释放,因此我们要这样做

try{

  执行的代码块

}finally{

  lock.unlock();

}

java5中的lock比传统的synchronized方式更强,可以实现读写锁的操作.

读写锁:分为读锁和写锁,多个读锁不互斥,读锁与写锁互斥,写锁与写锁互斥,,这是有jvm自己控制的,你只要上好相应的锁即可。如果你的代码只读数据,可以很多人同时读,但不能同时写,那就上读锁;如果你的代码修改数据,只能有一个人在写,且不能同时读取,那就上写锁。总之,读的时候上读锁,写的时候上写锁!一个面试题:写一个缓存类!

posted @ 2015-08-19 22:22  风云再起  阅读(127)  评论(0)    收藏  举报