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

Thinking in java并发

2016-05-16 07:10 405 查看

定义任务

线程可以驱动任务,我们通过实现 Runnable 接口来提供,需要实现 Runnable 接口的 run() 方法。

package com.kevindai.concurrency;

public class LiftOff  implements Runnable{

protected int countDown = 10;
private static int taskCount = 0;
private final int id = taskCount++;
public LiftOff() {

}

public LiftOff(int countDown) {
super();
this.countDown = countDown;
}
public String status() {
return "#" + id + "(" + (countDown > 0 ? countDown : "LiftOff") + "),";
}

@Override
public void run() {
while (countDown-- > 0) {
System.out.print(status());
Thread.yield();//线程调度器;建议进行线程调度
}
System.out.println();
}
public static void main(String[] args) {
LiftOff liffOff = new LiftOff();
liffOff.run();
}
}


输出:



我们也可以通过继承 Thread 类覆盖 run() 方法来实现线程类,但继承Thread类有一个缺点就是单继承,而实现Runnable接口则弥补了它的缺点,可以实现多继承。而且实现 Runnable 接口适合多线程共享资源,继承 Thread 类适合各个线程完成自己的任务,因为继承 Thread 类相当于每个线程有一份各自的资源,而实现 Runnable 还可以让多个线程共享一份代码。

Thread类

在代码中一般的使用方式都是将 Runnable 对象转变为任务的过程交给给一个 Thread 构造器。

package com.kevindai.concurrency;

public class BasicThreads {
public static void main(String[] args) {
Thread th = new Thread(new LiftOff());
th.start();
System.out.println("waiting for LiftOff");
}
}


Thread 构造器只需要一个 Runnable 对象。调用 Thread 对象的 start() 方法为该线程执行必须的初始化操作,然后内部调用 Runnable 的 run() 方法。

本Markdown编辑器使用[StackEdit][6]修改而来,用它写博客,将会带来全新的体验哦:

使用 Executor

使用线程池来分配线程

package com.kevindai.concurrency;

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

public class CachedThreadPool {
public static void main(String[] args) throws InterruptedException, ExecutionException {
ExecutorService exec = Executors.newCachedThreadPool();
for(int i = 0;i < 5;i++){
exec.execute(new LiftOff());
}
exec.shutdown();
}
}


线程池主要的实现主要包括以下几种:

CacheThreadPool:为每个任务都创建一个线程

FixedThreadPool:一次性预先分配好固定数量的线程

SingleThreadExecutor:线程数唯一,提交多个任务会排队等候

ScheduledThreadPool:创建一个定长线程池,支持定时及周期性任务执行。

从任务中产生返回值

如果我们希望任务完成时能够返回一个值,那么可以实现 Callable 接口而不是 Runnable 接口,实现 Callable 接口要求覆盖 Call() 方法。(用此方法使项目的中一个功能的运行速度提高了5倍以上)

package com.kevindai.concurrency;

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

public class CachedThreadPool {
@SuppressWarnings("unchecked")
public static void main(String[] args) throws InterruptedException, ExecutionException {
ExecutorService exec = Executors.newCachedThreadPool();
Future<?> f1 = null;
String str1 = "";
for(int i = 0;i < 5;i++){
f1 = exec.submit(new TestReturn("test1", "test2", "", "", "", "", "", ""));
str1 += f1.get();
}
System.out.println(str1);

}
}

package com.kevindai.concurrency;

import java.util.concurrent.Callable;

@SuppressWarnings("rawtypes")
public class TestReturn implements Callable{
private String originalPathList;
private String dhsList;
private String originalIP;
private String originalDirPath;
private String originalType;
private String idsList;
private String isMedia;
private String type;

public TestReturn(String originalPathList, String dhsList,
String originalIP, String originalDirPath, String originalType,
String idsList, String isMedia, String type) {
super();
this.originalPathList = originalPathList;
this.dhsList = dhsList;
this.originalIP = originalIP;
this.originalDirPath = originalDirPath;
this.originalType = originalType;
this.idsList = idsList;
this.isMedia = isMedia;
this.type = type;
}

@Override
public Object call() throws Exception {
return originalPathList + dhsList.toString();
}

}


优先级

线程的优先级将该线程的重要性传递给了调度器。调度器会倾向于让优先级高的线程先

使用方法:Thread.currentThread().setPriority(priority);


自己测试了没测试出什么效果,不写例子了,知道用法就好了

加入线程

一个线程可以在其他线程之上调用 join() 方法,其效果是等待一段时间直到第二个线程结束才继续执行。join() 调用时可以携带超时参数。

package com.kevindai.concurrency.join;

public class Sleeper extends Thread {
private int duration;
public Sleeper(String name,int sleepTime){
super(name);
duration = sleepTime;
start();
}

public void run(){
try {
sleep(duration);
} catch (InterruptedException e) {
System.out.println(getName() + " was interrupted." + "isInterrupted():" + isInterrupted());
return;
}
System.out.println(getName() + " has awakened");
}
}

package com.kevindai.concurrency.join;

public class Joiner extends Thread {
private Sleeper sleeper;
public Joiner(String name,Sleeper sleeper){
super(name);
this.sleeper = sleeper;
start();
}

public void run(){
try {
sleeper.join();
} catch (InterruptedException e) {
System.out.println("Interrupted");
}
System.out.println(getName() + " join completed");
}
}

package com.kevindai.concurrency.join;

public class Joining {
public static void main(String[] args) {
Sleeper sleepy = new Sleeper("Sleepy", 1500),
grumpy = new Sleeper("Grumpy", 1500);

Joiner dopey = new Joiner("Dopey", sleepy),
doc = new Joiner("Doc", grumpy);
grumpy.interrupt();
}
}


输出:



共享资源

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: