方法一:繼承Thread類,作為線程對象存在(繼承Thread對象)
public class CreatThreadDemo1 extends Thread{
/**
* 構(gòu)造方法: 繼承父類方法的Thread(String name);方法
* @param name
*/
public CreatThreadDemo1(String name){
super(name);
}
@Override
public void run() {
while (!interrupted()){
System.out.println(getName()+"線程執(zhí)行了...");
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
CreatThreadDemo1 d1 = new CreatThreadDemo1("first");
CreatThreadDemo1 d2 = new CreatThreadDemo1("second");
d1.start();
d2.start();
d1.interrupt(); //中斷第一個線程
}
}
常規(guī)方法音比,不多做介紹了,interrupted方法氢惋,是來判斷該線程是否被中斷洞翩。(終止線程不允許用stop方法,該方法不會施放占用的資源焰望。所以我們在設(shè)計程序的時候骚亿,要按照中斷線程的思維去設(shè)計,就像上面的代碼一樣)熊赖。
讓線程等待的方法
- Thread.sleep(200); //線程休息2ms
- Object.wait()来屠; //讓線程進(jìn)入等待,直到調(diào)用Object的notify或者notifyAll時震鹉,線程停止休眠
方法二:實(shí)現(xiàn)runnable接口俱笛,作為線程任務(wù)存在
public class CreatThreadDemo2 implements Runnable {
@Override
public void run() {
while (true){
System.out.println("線程執(zhí)行了...");
}
}
public static void main(String[] args) {
//將線程任務(wù)傳給線程對象
Thread thread = new Thread(new CreatThreadDemo2());
//啟動線程
thread.start();
}
}
Runnable 只是來修飾線程所執(zhí)行的任務(wù),它不是一個線程對象传趾。想要啟動Runnable對象嫂粟,必須將它放到一個線程對象里。
方法三:匿名內(nèi)部類創(chuàng)建線程對象
public class CreatThreadDemo3 extends Thread{
public static void main(String[] args) {
//創(chuàng)建無參線程對象
new Thread(){
@Override
public void run() {
System.out.println("線程執(zhí)行了...");
}
}.start();
//創(chuàng)建帶線程任務(wù)的線程對象
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("線程執(zhí)行了...");
}
}).start();
//創(chuàng)建帶線程任務(wù)并且重寫run方法的線程對象
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("runnable run 線程執(zhí)行了...");
}
}){
@Override
public void run() {
System.out.println("override run 線程執(zhí)行了...");
}
}.start();
}
}
創(chuàng)建帶線程任務(wù)并且重寫run方法的線程對象中墨缘,為什么只運(yùn)行了Thread的run方法星虹。我們看看Thread類的源碼,镊讼,我們可以看到Thread實(shí)現(xiàn)了Runnable接口宽涌,而Runnable接口里有一個run方法。
所以蝶棋,我們最終調(diào)用的重寫的方法應(yīng)該是Thread類的run方法卸亮。而不是Runnable接口的run方法。
方法四:創(chuàng)建帶返回值的線程
public class CreatThreadDemo4 implements Callable {
public static void main(String[] args) throws ExecutionException, InterruptedException {
CreatThreadDemo4 demo4 = new CreatThreadDemo4();
FutureTask<Integer> task = new FutureTask<Integer>(demo4); //FutureTask最終實(shí)現(xiàn)的是runnable接口
Thread thread = new Thread(task);
thread.start();
System.out.println("我可以在這里做點(diǎn)別的業(yè)務(wù)邏輯...因?yàn)镕utureTask是提前完成任務(wù)");
//拿出線程執(zhí)行的返回值
Integer result = task.get();
System.out.println("線程中運(yùn)算的結(jié)果為:"+result);
}
//重寫Callable接口的call方法
@Override
public Object call() throws Exception {
int result = 1;
System.out.println("業(yè)務(wù)邏輯計算中...");
Thread.sleep(3000);
return result;
}
}
Callable接口介紹:
public interface Callable<V> {
/**
* Computes a result, or throws an exception if unable to do so.
*
* @return computed result
* @throws Exception if unable to compute a result
*/
V call() throws Exception;
}
返回指定泛型的call方法玩裙。然后調(diào)用FutureTask對象的get方法得道call方法的返回值兼贸。
方法五:定時器Timer
public class CreatThreadDemo5 {
public static void main(String[] args) {
Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
System.out.println("定時器線程執(zhí)行了...");
}
},0,1000); //延遲0,周期1s
}
}
方法六:線程池創(chuàng)建線程
public class CreatThreadDemo6 {
public static void main(String[] args) {
//創(chuàng)建一個具有10個線程的線程池
ExecutorService threadPool = Executors.newFixedThreadPool(10);
long threadpoolUseTime = System.currentTimeMillis();
for (int i = 0;i<10;i++){
threadPool.execute(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"線程執(zhí)行了...");
}
});
}
long threadpoolUseTime1 = System.currentTimeMillis();
System.out.println("多線程用時"+(threadpoolUseTime1-threadpoolUseTime));
//銷毀線程池
threadPool.shutdown();
threadpoolUseTime = System.currentTimeMillis();
}
}
方法七:利用java8新特性 stream 實(shí)現(xiàn)并發(fā)
lambda表達(dá)式不懂的吃溅,可以看看我的java8新特性文章:
java8-lambda:http://www.reibang.com/p/3a08dc78a05f
java8-stream:http://www.reibang.com/p/ea16d6712a00
public class CreatThreadDemo7 {
public static void main(String[] args) {
List<Integer> values = Arrays.asList(10,20,30,40);
//parallel 平行的溶诞,并行的
int result = values.parallelStream().mapToInt(p -> p*2).sum();
System.out.println(result);
//怎么證明它是并發(fā)處理呢
values.parallelStream().forEach(p-> System.out.println(p));
}
}
200
40
10
20
30
怎么證明它是并發(fā)處理呢,他們并不是按照順序輸出的 。