1,到目前为止,你学到的都是有关顺序编程的知识,即程序中的所有的事物在任意时刻都只能执行一个步骤。
2,java是一门多线程的语言,并且提出了并发问题。
3,你无法选择何时在你的java程序中出现线程,仅仅是你没有启动线程并不代表你就可以回避编写使用线程的代码。
例如,Web系统是最常见的java应用系统之一,而基本的Web类库、Servlet具有天生的多线程特性,这很重要,
因为Web服务器经常包含多个处理器,而并发是充分利用这些处理器的理想方式。即使是Servlet这样的看起来很简单的
情况。你也必须理解并发问题,从而正确的使用它们。图形化界面也是类似的情况,尽管SWing和SWT类库都拥有针对
线程安全的机制,但是不理解并发,你就很难了解如何正确的使用它们。
4,定义任务,线程可以驱动任务,因此你需要一种描述任务的方式,这可以有Runnable接口来提供。
public class LiftOff implements Runnable {
protected int countDown = 10; // Default
private static int taskCount = 0;
private final int id = taskCount++;
public LiftOff() {}
public LiftOff(int countDown) {
this.countDown = countDown;
}
public String status() {
return "#" + id + "(" +
(countDown > 0 ? countDown : "Liftoff!") + "), ";
}
public void run() {
while(countDown-- > 0) {
System.out.print(status());
Thread.yield(); //是切换到别的线程的时机了
}
}
} ///:~
应用这个任务:
public class MainThread {
public static void main(String[] args) {
LiftOff launch = new LiftOff();
launch.run();
}
} /* Output
输出结果是:
#0(9), #0(8), #0(7), #0(6), #0(5), #0(4), #0(3), #0(2), #0(1), #0(Liftoff!),
4,也可以将Runnable对象转变为工作任务的传统方式把它提交到Thread的构造器。
public class BasicThreads {
public static void main(String[] args) {
Thread t = new Thread(new LiftOff());
t.start();
System.out.println("Waiting for LiftOff");
}
} /* Output: (90% match)
Start方法迅速返回的。
可以启动更多的任务:
public class MoreBasicThreads {
public static void main(String[] args) {
for(int i = 0; i < 5; i++)
new Thread(new LiftOff()).start();
System.out.println("Waiting for LiftOff");
}
} /* Output
结果是:
Waiting for LiftOff
#0(9), #1(9), #3(9), #4(9), #2(9), #1(8), #4(8), #0(8), #3(8), #2(8), #1(7), #4(7), #3(7), #2(7), #0(7), #1(6), #4(6), #3(6), #2(6), #1(5), #4(5), #0(6), #3(5), #2(5), #4(4), #0(5), #3(4), #1(4), #2(4), #4(3), #0(4), #3(3), #2(3), #0(3), #1(3), #3(2), #4(2), #2(2), #0(2), #4(1), #2(1), #1(2), #3(1), #4(Liftoff!), #1(1), #0(1), #3(Liftoff!), #1(Liftoff!), #2(Liftoff!), #0(Liftoff!),
5,使用Executor
java SE5的java.util.concurrent包中的执行器(Exector)将为你管理Thread对象,从而简化了并发编程。
Excutor在客户端和任务执行之间提供了一个间接层:与客户端直接执行任务不同,这个中介对象将执行任务。
Excutor允许你管理异步任务,而无需显式的管理现成的生命周期,Executor是java SE 5/6启动任务的优先选择。
public class CachedThreadPool {
public static void main(String[] args) {
ExecutorService exec = Executors.newCachedThreadPool();
for(int i = 0; i < 5; i++)
exec.execute(new LiftOff());
exec.shutdownNow();
System.out.println("shutdown now!!");
}
} /* Output:
shutdown()方法可以防止新的任务提交到这个Executor。运行完已经提交的任务马上退出。
shutdownnow()方法立即关闭。不运行现在的任务,立即退出。
public class FixedThreadPool {
public static void main(String[] args) {
// Constructor argument is number of threads:
ExecutorService exec = Executors.newFixedThreadPool(5); //固定大小的线程池
for(int i = 0; i < 5; i++)
exec.execute(new LiftOff());
exec.shutdown();
}
} /* Output: (Sample)
public class SingleThreadExecutor {
public static void main(String[] args) {
ExecutorService exec = Executors.newSingleThreadExecutor();//相当于线程数为1的的newFixedThreadPool
for(int i = 0; i < 5; i++)
exec.execute(new LiftOff());
exec.shutdown();
}
} /* Output
6,如果希望任务有返回值,用Callable做接口
class TaskWithResult implements Callable<String> {
private int id;
public TaskWithResult(int id) {
this.id = id;
}
public String call() {
return "result of TaskWithResult " + id;
}
}
public class CallableDemo {
public static void main(String[] args) {
ExecutorService exec = Executors.newCachedThreadPool();
ArrayList<Future<String>> results =
new ArrayList<Future<String>>();
for(int i = 0; i < 10; i++)
results.add(exec.submit(new TaskWithResult(i)));
for(Future<String> fs : results)
try {
// get() blocks until completion:
if(fs.isDone())
System.out.println(fs.get());
} catch(InterruptedException e) {
System.out.println(e);
return;
} catch(ExecutionException e) {
System.out.println(e);
} finally {
exec.shutdown();
}
}
} /* Output:
运行结果是:
result of TaskWithResult 0
result of TaskWithResult 1
result of TaskWithResult 2
result of TaskWithResult 3
result of TaskWithResult 4
result of TaskWithResult 5
result of TaskWithResult 6
result of TaskWithResult 7
result of TaskWithResult 8
result of TaskWithResult 9
6,休眠调用sleep。
public class SleepingTask extends LiftOff {
public void run() {
try {
while(countDown-- > 0) {
System.out.print(status());
// Old-style:
Thread.sleep(500);
// Java SE5/6-style:
//TimeUnit.MILLISECONDS.sleep(100);
}
} catch(InterruptedException e) {
System.err.println("Interrupted");
}
}
public static void main(String[] args) {
ExecutorService exec = Executors.newCachedThreadPool();
for(int i = 0; i < 5; i++)
exec.execute(new SleepingTask());
exec.shutdown();
}
} /* Output:
7,优先级
public class SimplePriorities implements Runnable {
private int countDown = 5;
private volatile double d; // No optimization
private int priority;
public SimplePriorities(int priority) {
this.priority = priority;
}
public String toString() {
return Thread.currentThread() + ": " + countDown;
}
public void run() {
Thread.currentThread().setPriority(priority);
while(true) {
// An expensive, interruptable operation:
for(int i = 1; i < 100000; i++) {
d += (Math.PI + Math.E) / (double)i;
if(i % 1000 == 0)
Thread.yield();
}
System.out.println(this);
if(--countDown == 0) return;
}
}
public static void main(String[] args) {
ExecutorService exec = Executors.newCachedThreadPool();
for(int i = 0; i < 5; i++)
exec.execute(
new SimplePriorities(Thread.MIN_PRIORITY));
exec.execute(
new SimplePriorities(Thread.MAX_PRIORITY));
exec.shutdown();
}
} /* Output: (70% match)
8,后台线程
所有后台(daemon)线程,是指在程序运行的时候在后台提供一种通用的服务。并且这种线程并不属于程序的不可或缺
的部分。因此,当所有的非后台线程结束时,程序也就终止了。同时会杀死所有后台线程。反过来,只有任何非后台线程还
在运行,程序就不会终止。
public class SimpleDaemons implements Runnable {
public void run() {
try {
while(true) {
TimeUnit.MILLISECONDS.sleep(100);
print(Thread.currentThread() + " " + this);
}
} catch(InterruptedException e) {
print("sleep() interrupted");
}
}
public static void main(String[] args) throws Exception {
for(int i = 0; i < 10; i++) {
Thread daemon = new Thread(new SimpleDaemons());
daemon.setDaemon(true); // Must call before start()
daemon.start();
}
print("All daemons started");
TimeUnit.MILLISECONDS.sleep(100);
}
} /
运行结果:
All daemons started
Thread[Thread-3,5,main] SimpleDaemons@15ff48b
Thread[Thread-8,5,main] SimpleDaemons@1be2d65
Thread[Thread-6,5,main] SimpleDaemons@affc70
Thread[Thread-0,5,main] SimpleDaemons@1e63e3d
Thread[Thread-9,5,main] SimpleDaemons@1004901
Thread[Thread-2,5,main] SimpleDaemons@1b90b39
Thread[Thread-5,5,main] SimpleDaemons@18fe7c3
Thread[Thread-7,5,main] SimpleDaemons@b8df17
Thread[Thread-4,5,main] SimpleDaemons@13e8d89
Thread[Thread-1,5,main] SimpleDaemons@9664a1
后台线程会在不执行finally子句的情况下终止其run()方法
class ADaemon implements Runnable {
public void run() {
try {
print("Starting ADaemon");
TimeUnit.SECONDS.sleep(1);
} catch(InterruptedException e) {
print("Exiting via InterruptedException");
} finally {
print("This should always run?");
}
}
}
public class DaemonsDontRunFinally {
public static void main(String[] args) throws Exception {
Thread t = new Thread(new ADaemon());
t.setDaemon(true);
t.start();
}
} /* Output:
Starting ADaemon
*///:~
结果:
Starting ADaemon
没有运行finally子句。
9,其他的形式的线程任务:
public class SimpleThread extends Thread {
private int countDown = 5;
private static int threadCount = 0;
public SimpleThread() {
// Store the thread name:
super(Integer.toString(++threadCount));
//start();
}
public String toString() {
return "#" + getName() + "(" + countDown + "), ";
}
public void run() {
while(true) {
System.out.print(this);
if(--countDown == 0)
return;
}
}
public static void main(String[] args) {
for(int i = 0; i < 5; i++)
new SimpleThread().start();
}
} /* Output:
和以下的:
public class SelfManaged implements Runnable {
private int countDown = 5;
private Thread t = new Thread(this);
public SelfManaged() { t.start(); }
public String toString() {
return Thread.currentThread().getName() +
"(" + countDown + "), ";
}
public void run() {
while(true) {
System.out.print(this);
if(--countDown == 0)
return;
}
}
public static void main(String[] args) {
for(int i = 0; i < 5; i++)
new SelfManaged();
}
} /* Output:
10,join入一个线程
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) {
print(getName() + " was interrupted. " +
"isInterrupted(): " + isInterrupted());
return;
}
print(getName() + " has awakened");
}
}
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) {
print("Interrupted");
}
print(getName() + " join completed");
}
}
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();
}
} /* Output:
11,无法用try,catch来捕获异常
public class ExceptionThread implements Runnable {
public void run() {
throw new RuntimeException();
}
public static void main(String[] args) {
ExecutorService exec = Executors.newCachedThreadPool();
exec.execute(new ExceptionThread());
}
} ///:~
和
public class NaiveExceptionHandling {
public static void main(String[] args) {
try {
ExecutorService exec =
Executors.newCachedThreadPool();
exec.execute(new ExceptionThread());
} catch(RuntimeException ue) {
// This statement will NOT execute!
System.out.println("Exception has been handled!");
}
}
} ///:~
无法捕获异常:
Exception in thread "pool-1-thread-1" java.lang.RuntimeException
at ExceptionThread.run(ExceptionThread.java:7)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
需要banding一个异常处理器:
class ExceptionThread2 implements Runnable {
public void run() {
Thread t = Thread.currentThread();
System.out.println("run() by " + t);
System.out.println(
"eh = " + t.getUncaughtExceptionHandler());
throw new RuntimeException();
}
}
class MyUncaughtExceptionHandler implements
Thread.UncaughtExceptionHandler {
public void uncaughtException(Thread t, Throwable e) {
System.out.println("caught " + e);
}
}
class HandlerThreadFactory implements ThreadFactory {
public Thread newThread(Runnable r) {
System.out.println(this + " creating new Thread");
Thread t = new Thread(r);
System.out.println("created " + t);
t.setUncaughtExceptionHandler(
new MyUncaughtExceptionHandler());
System.out.println(
"eh = " + t.getUncaughtExceptionHandler());
return t;
}
}
public class CaptureUncaughtException {
public static void main(String[] args) {
ExecutorService exec = Executors.newCachedThreadPool(
new HandlerThreadFactory());
exec.execute(new ExceptionThread2());
}
} /* Output: (90% match)
结果是:
HandlerThreadFactory@42719c creating new Thread
created Thread[Thread-0,5,main]
eh = MyUncaughtExceptionHandler@119298d
run() by Thread[Thread-0,5,main]
eh = MyUncaughtExceptionHandler@119298d
caught java.lang.RuntimeException
捕获了异常。
分享到:
相关推荐
本压缩包中包含的"Example"文件夹,极有可能是《JAVA学习笔记》一书中的实例源代码,旨在帮助读者深入理解书中讲解的Java编程原理和实践技巧。下面我们将对这些源代码进行详细解读,以便更好地掌握Java编程。 1. **...
Java并发编程学习笔记,研究JAVA并发多线程编程的一本教程,使用并发技术可以开发出并行算法,充分利用多处理器的计算能力,避免硬件资源浪费。目前,在JAVA并发编程方面的论述系统且内容详实的技术资料不太多,Java...
这本"Java并发编程学习笔记"可能是作者在深入研究Java并发特性、工具和最佳实践过程中积累的心得体会。下面,我们将根据这个主题,探讨一些关键的Java并发编程知识点。 1. **线程与进程**:在多任务环境中,线程是...
java多线程并发编程知识导图笔记.xmind
Java并发编程是Java开发中必不可少的一部分,涉及到多线程、同步机制、线程池以及并发工具类等多个核心知识点。以下是对这些主题的详细说明: 1. **线程安全与锁 Synchronized 底层实现原理**: 线程安全是指在多...
在Java编程中,多线程是一项关键技能,它允许程序...通过深入学习和实践这些知识点,我们可以更好地理解和掌握Java多线程编程,提升程序的并发性能。结合源码分析和实际工具的使用,将使我们成为Java多线程领域的专家。
2. **确保正确性优先于性能:** 多线程编程中,首先确保程序逻辑的正确性,然后再考虑如何优化性能。 3. **无状态或只读对象是线程安全的:** 如果一个对象不包含任何状态信息(即无状态)或其状态不会改变(只读)...
Java并发编程实践是Java开发中不可或缺的一个领域,它涉及到如何高效、正确地处理多线程环境中的任务。这本书的读书笔记涵盖了多个关键知识点,旨在帮助读者深入理解Java并发编程的核心概念。 1. **线程和进程的...
### Java并发编程学习笔记知识点详解 #### 一、Java并发编程概述 Java并发编程是指在Java应用程序中同时执行多个操作的技术。它通过多线程、线程池等机制实现资源的有效利用,提高程序运行效率。Java并发编程的...
### Java编程思想读书笔记 #### 一、Java与C++的区别及内存管理 在学习Java的过程中,我们常常会拿它与C++进行比较。这两门语言虽然有着相似之处,但也有许多不同点。 1. **内存管理:** - C++提供了更为底层的...
java学习笔记2(多线程)java学习笔记2(多线程)
### Java分布式应用学习笔记05多线程下的并发同步器 #### 1. 前言 在现代软件开发中,特别是在分布式系统和高性能计算领域,有效地管理多线程之间的协同工作至关重要。Java语言提供了丰富的工具和API来帮助开发者...
在讨论Java编程思想学习笔记时,首先需要了解的是Java语言的平台无关性,而这一特性正是通过Java虚拟机(JVM)得以实现的。JVM作为Java程序设计的关键组成部分,对于Java开发人员来说是必须掌握的基础知识。在该学习...
### Java并发编程知识点详解 #### 一、线程状态与管理 在Java中,线程具有多种状态,这些状态的变化反映了线程在其生命周期中的不同阶段。理解这些状态及其转换对于编写高效、健壮的并发程序至关重要。 - **NEW**...
GCD的使用更为简单和面向对象,它的目的是简化多线程编程,使得开发者能够更加方便地实现并发执行。 GCD中执行任务的两个常用函数是dispatch_sync和dispatch_async。dispatch_sync函数用于同步执行任务,它将任务...
│ 高并发编程第二阶段21讲、多线程Future设计模式详细介绍-上.mp4 │ 高并发编程第二阶段22讲、多线程Future设计模式详细介绍-下.mp4 │ 高并发编程第二阶段23讲、第二阶段课程答疑学员问题.mp4 │ 高并发编程...