您的位置:首页 > 编程语言 > Java开发

Java线程

2015-08-19 22:22 489 查看
传统线程机制

线程的实现方法

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

package com.lsf.test.thread;

public class MyTraditionalThreadCommunitation {
public static void main(String[] args) {
final MyBusiness myBusiness = new MyBusiness();
new Thread(
new Runnable() {
@Override
public void run() {
for(int i=1;i<=50;i++){
myBusiness.sub(i);
}
}
}
).start();

for(int i=1;i<=50;i++){
myBusiness.main(i);
}
}

}

class MyBusiness{
private boolean isShowSub = true;
public synchronized void sub(int i){
while(!isShowSub){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}

for(int j=1;j<=10;j++){
System.out.println("子线程循环->"+ j +",循环了->"+i);
}
isShowSub = false;
this.notify();
}

public synchronized void main(int i){
while(isShowSub){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}

for(int j=1;j<=10;j++){
System.out.println("主线程循环->"+ j +",循环了->"+i);
}
isShowSub=true;
this.notify();
}
}


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

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

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

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

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

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

Java5中的线程并发库

线程池

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

  创建固定大小的线程池

  创建缓存线程池

  创建单一线程池

关闭线程池

线程池启动定时器

Callable&Future

     ExecutorService threadPool2 = Executors.newFixedThreadPool(10);
CompletionService<Integer> completionService = new ExecutorCompletionService<Integer>(threadPool2);
for(int i=1;i<=10;i++){
final int seq = i;
completionService.submit(new Callable<Integer>() {
@Override
public Integer call() throws Exception {
Thread.sleep(new Random().nextInt(5000));
return seq;
}
});
}

for(int i=0;i<10;i++){
try {
System.out.println(completionService.take().get());
} catch (Exception e) {
e.printStackTrace();
}
}


Lock&Condition实现线程同步通信

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

新建锁对象

Lock lock = new ReentrantLock();

lock.lock();  //开启锁

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

try{

  执行的代码块

}finally{

  lock.unlock();

}

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

读写锁:分为读锁和写锁,多个读锁不互斥,读锁与写锁互斥,写锁与写锁互斥,,这是有jvm自己控制的,你只要上好相应的锁即可。如果你的代码只读数据,可以很多人同时读,但不能同时写,那就上读锁;如果你的代码修改数据,只能有一个人在写,且不能同时读取,那就上写锁。总之,读的时候上读锁,写的时候上写锁!一个面试题:写一个缓存类!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: