常见误解情况:
Thread.yield(): 放弃当前的cpu时间片,进入ready to run状态. 错
Thread.yield():建议放弃当前cpu时间片,但是否放弃由jvm决定。
Java 5新特性:
ExecutorService exec = Executors.newCachedThreadPool();
exec.execute( new MyThread1(););
exec.execute(new MyThread2());
exec.shutdown();
Executors.newCachedThreadPool();
Executors.newFixedThreadPool(5);
Executors.newSingleThreadExecutor();// 等于Executors.newFixedThreadPool(1);
java 不建议直接使用线程,而是添加了executors类,我们使用的时候只需要将需要做的事情放入exec.execute()中,设定执行的线程数,其余的事情由java调度。
Executors.newSingleThreadExecutor():一个线程顺序执行放入的任务。
execute.submit(Callable )返回Future类,可以异步的查看线程运行状况已经运行结果。
Lock lock = new ReentrantLock();
lock.lock();
try{
code block;
}finally{
lock.unlock();
}
可以显式的调用lock实现线程工作。
锁:
对象锁:每个对象上都有一把锁,但一个线程获得这个对象锁后,其他线程将被阻塞,直到获得对象锁的线程释放该锁。
1. 当synchronized直接修饰方法时,进入该方法的线程获得的是该方法对应实例的对象锁。
2. 当synchronized直接修饰代码块的时候,synchronized(**){code block}, 线程获得的是对象**的锁。
类锁:当synchronized修饰静态方法的时候,静态方法获得的是类锁。
1. public static synchronized void instance(){code block}, 调用该方法的线程获得的是该方法从属的类的锁。
(底层实现:
对象锁计数器初始化为0,当获得对象锁的对象多次获得对象锁的同时,对象锁计数器会累加。当计数器为0的时候,其他线程才能获得对象锁。)
多线程协作:
wait()和notify()用来是当前线程挂起或者唤醒。
他们作为Object基类的一部分是因为他们都是操作锁的,锁是所有对象的一部分而非Thread特有。
wait()的含义:我已经做完线程该做的事情,且等待其他线程或者资源。所以释放对象锁,等待再次被唤醒。
wait()可以防止线程忙等待。
若wait()的使用没有获得锁则抛出IllegalMonitorStateException
。
wait()使用必须获得锁,且notify()使用也必须获得锁,且notify()唤醒的是notify()所获得锁所对应的wait()方法。
class MyThread1 implements Runnable {
public boolean flag = true;
Object syncObject = new Object();
@Override
public void run() {
synchronized (syncObject
) {
System.out.println("Entry thread 1");
while (flag) {
System.out.println("thread 1 wait");
try {
syncObject.wait();
} catch (InterruptedException e1) {
e1.printStackTrace();
}
}
System.out.println("Out of thread 1");
}
}
}
class MyThread2 implements Runnable {
Runnable runnable;
public MyThread2(Runnable runnable) {
this.runnable = runnable;
}
@Override
public synchronized void run() {
System.out.println("Entry thread 2");
int i = 0;
while (((MyThread1)runnable).flag) {
synchronized (((MyThread1)runnable).syncObject
) {
i++;
if (i == 5) {
((MyThread1)runnable).flag = false;
}
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
((MyThread1)runnable).syncObject.notifyAll();
System.out.println("thread 2 notify.");
}
}
System.out.println("Out of thread 2");
}
}
public class WaitAndNotify {
public static void main(String[] args) {
ExecutorService exec = Executors.newCachedThreadPool();
Runnable a = new MyThread1();
exec.execute(a);
exec.execute(new MyThread2(a));
exec.shutdown();
}
}
以上例子,wait和notify获得的都是syncObject的锁,若在synchronized方法中直接使用wait那么wait获得的锁是当前对象的锁。那么notify也必须获得与wait对应一样的锁才能唤醒wait的线程。
wait(Time)和sleep(Time)的区别:都表示等待Time时间后继续运行,但是wait()会释放锁,sleep不会释放锁。当没有获得锁的情况中只能使用sleep().
中断
:
t.interrupt(),t.isInterrupted(),Thread.interrupted()
t.interrupt():会设置这个线程的中断状态为true
。且对于如果一个线程已经被阻塞或者试图执行一个阻塞操作,那么这个线程会抛出InterruptedException
,对于sleep和wait方法都会默认捕捉InterruptedException方法。
当调用t.interrupt()后再调用t.isInterrupted()线程true。
当有别的线程调用了本线程的interrupt( )时,会设置一个标记以表示这个这个线程被打断了。当本线程捕获这个异常的时候,会清除这个标志。所以catch语句会永远报告说isInterrupted( )是false。这个标记是用来应付其它情况的,或许在没出异常的情况下,线程要用它来检查自己是不是被中断了。
Thread.interrupted()调用过后会清除了其中断状态.
官方API:
interrupt
public void interrupt
()
中断线程。
如果当前线程没有中断它自己(这在任何情况下都是允许的),则该线程的 checkAccess
方法就会被调用,这可能抛出 SecurityException
。
如果线程在调用 Object
类的 wait()
、wait(long)
或 wait(long,
int)
方法,或者该类的 join()
、join(long)
、join(long,
int)
、sleep(long)
或 sleep(long,
int)
方法过程中受阻,则其中断状态将被清除,它还将收到一个 InterruptedException
。
如果该线程在可
中断的通道
上的 I/O 操作中受阻,则该通道将被关闭,该线程的中断状态将被设置并且该线程将收到一个 ClosedByInterruptException
。
如果该线程在一个 Selector
中受阻,则该线程的中断状态将被设置,它将立即从选择操作返回,并可能带有一个非零值,就好像调用了选择器的 wakeup
方法一样。
如果以前的条件都没有保存,则该线程的中断状态将被设置。
抛出:
SecurityException
- 如果当前线程无法修改该线程
<!-- -->
interrupted
public static boolean interrupted
()
测试当前线程是否已经中断。线程的中断状态
由该方法清除。换句话说,如果连续两次调用该方法,则第二次调用将返回
false(在第一次调用已清除了其中断状态之后,且第二次调用检验完中断状态前,当前线程再次中断的情况除外)。
返回:
如果当前线程已经中断,则返回 true
;否则返回 false
。
另请参见:
isInterrupted()
<!-- -->
isInterrupted
public boolean isInterrupted
()
测试线程是否已经中断。线程的中断状态
不受该方法的影响。
返回:
如果该线程已经中断,则返回 true
;否则返回 false
。
另请参见:
interrupted()
t.interrupt()不会中断正在执行的线程,只是将线程的标志位设置成true。但是如果线程在调用sleep(),join(),wait()
方法时线程被中断,则这些方法会抛出InterruptedException,在catch块中捕获到这个异常时,线程的中断标志位已经被设置成
false了,因此在此catch块中调用t.isInterrupted(),Thread.interrupted()始终都为false,
而t.isInterrupted与Thread.interrupted()的区别是API中已经说明很明显
了,Thread.interrupted()假如当前的中断标志为true,则调完后会将中断标志位设置成false
分享到:
相关推荐
锁是Java并发编程中用于同步的关键工具。书中深入剖析了各种锁机制,如内置锁(也称为监视器锁),通过`synchronized`关键字实现。此外,还介绍了高级的锁接口`java.util.concurrent.locks`,如`ReentrantLock`,它...
- **Java并发机制**:Java提供了丰富的并发机制来支持多线程程序的编写,包括但不限于`Thread`类、`Runnable`接口、`Callable`接口以及`Executor`框架等。 - **锁机制**:Java中的锁机制主要包括synchronized关键字...
锁机制是Java并发编程中的另一大主题,包括内置锁(互斥锁)和显式锁(如`ReentrantLock`)。内置锁是`synchronized`关键字提供的,而显式锁提供了更细粒度的控制和更丰富的功能。书中可能还会讨论读写锁(`...
《Java 并发编程实战》是一本专注于Java并发编程的权威指南,对于任何希望深入了解Java多线程和并发控制机制的开发者来说,都是不可或缺的参考资料。这本书深入浅出地介绍了如何在Java环境中有效地管理和控制并发...
总的来说,这份“java并发编程内部分享PPT”涵盖了Java并发编程的多个重要方面,包括线程创建与管理、同步机制、并发容器、线程池、并发问题以及异步计算。通过深入学习和实践这些知识点,开发者可以更好地应对多...
通过学习《Java并发编程实践》,开发者将能够更好地理解和利用Java平台的并发特性,编写出更高效、更可靠的多线程应用程序。无论是初级开发者还是经验丰富的专业人员,都能从这本书中收获宝贵的并发编程知识。
《JAVA并发编程艺术》是Java开发者深入理解和掌握并发编程的一本重要著作,它涵盖了Java并发领域的核心概念和技术。这本书详细阐述了如何在多线程环境下有效地编写高效、可靠的代码,对于提升Java程序员的技能水平...
Java并发API包括了线程、锁、同步、并发容器等丰富的工具,使得开发者可以构建能够充分利用多核处理器性能的应用程序。本书详细介绍了这些主题,并提供了实例代码和实践建议。 首先,书中详细讨论了Java线程的创建...
2. **同步机制**:Java并发编程的核心在于同步,以防止数据不一致性和资源竞争。`synchronized`关键字用于实现临界区的互斥访问,确保同一时刻只有一个线程执行特定代码块。此外,还有`wait()`, `notify()`, `...
"Java并发编程与实践"文档深入剖析了这一主题,旨在帮助开发者理解和掌握如何在Java环境中有效地实现并发。 并发是指在单个执行单元(如CPU)中同时执行两个或更多任务的能力。在Java中,这主要通过线程来实现,...
5. **ReentrantLock**: 这是可重入的互斥锁,比`synchronized`关键字更灵活,支持公平锁和非公平锁,以及可中断和定时等待。 6. **Atomic* 类**: 如AtomicInteger、AtomicLong等,提供了原子操作,保证在并发环境下...
基于Java并发编程的多线程同步与锁机制 项目简介 本项目旨在深入探讨Java并发编程中的多线程同步与锁机制,涵盖了从基础的线程创建、同步方法到高级的并发工具类如ReentrantLock、ReadWriteLock、Atomic类等的...
3. **锁**:Java并发库中的`java.util.concurrent.locks`包提供了更高级的锁机制,如可重入锁(`ReentrantLock`)、读写锁(`ReadWriteLock`)和条件变量(`Condition`),这些工具允许更灵活的控制并发访问。 4. **并发...
Java并发编程是Java高级特性之一,它允许开发者编写能够同时执行多个任务的程序,这对于提高应用程序的性能至关重要。下面将详细探讨Java并发编程中的关键概念、技术及实践技巧。 ### 一、Java并发编程基础 #### ...
《Java并发程序设计教程》是一本深入探讨Java平台上的并发编程技术的专业书籍。并发和多线程是现代软件开发中的核心概念,特别是在Java这样的多线程支持强大的编程语言中。这本书详细介绍了如何在Java环境中有效地...
Java并发编程涉及到许多关键概念,如线程、同步、锁、并发容器、原子变量以及并发工具类等。以下是一些主要的知识点: 1. **线程基础**:线程是程序执行的最小单位,Java中的`Thread`类提供了创建和管理线程的方法...
Java并发编程的核心组件包括线程、锁、同步、并发集合和并发工具类。线程是并发的基本执行单元,Java提供了Thread类来创建和控制线程。锁用于在多线程环境下控制共享资源的访问,Java提供了synchronized关键字和java...