`
zl198751
  • 浏览: 279565 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Java 并发机制(Java 5 新特性, Thread, 锁)

阅读更多

常见误解情况:

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 并发编程实战高清PDF版》

    锁是Java并发编程中用于同步的关键工具。书中深入剖析了各种锁机制,如内置锁(也称为监视器锁),通过`synchronized`关键字实现。此外,还介绍了高级的锁接口`java.util.concurrent.locks`,如`ReentrantLock`,它...

    Java 并发编程实战.pdf

    - **Java并发机制**:Java提供了丰富的并发机制来支持多线程程序的编写,包括但不限于`Thread`类、`Runnable`接口、`Callable`接口以及`Executor`框架等。 - **锁机制**:Java中的锁机制主要包括synchronized关键字...

    java并发编程艺术

    锁机制是Java并发编程中的另一大主题,包括内置锁(互斥锁)和显式锁(如`ReentrantLock`)。内置锁是`synchronized`关键字提供的,而显式锁提供了更细粒度的控制和更丰富的功能。书中可能还会讨论读写锁(`...

    (PDF带目录)《Java 并发编程实战》,java并发实战,并发

    《Java 并发编程实战》是一本专注于Java并发编程的权威指南,对于任何希望深入了解Java多线程和并发控制机制的开发者来说,都是不可或缺的参考资料。这本书深入浅出地介绍了如何在Java环境中有效地管理和控制并发...

    java并发编程内部分享PPT

    总的来说,这份“java并发编程内部分享PPT”涵盖了Java并发编程的多个重要方面,包括线程创建与管理、同步机制、并发容器、线程池、并发问题以及异步计算。通过深入学习和实践这些知识点,开发者可以更好地应对多...

    Java并发编程实践高清pdf及源码

    通过学习《Java并发编程实践》,开发者将能够更好地理解和利用Java平台的并发特性,编写出更高效、更可靠的多线程应用程序。无论是初级开发者还是经验丰富的专业人员,都能从这本书中收获宝贵的并发编程知识。

    JAVA并发编程艺术pdf版

    《JAVA并发编程艺术》是Java开发者深入理解和掌握并发编程的一本重要著作,它涵盖了Java并发领域的核心概念和技术。这本书详细阐述了如何在多线程环境下有效地编写高效、可靠的代码,对于提升Java程序员的技能水平...

    JAVA并发编程实践.pdf+高清版+目录 书籍源码

    Java并发API包括了线程、锁、同步、并发容器等丰富的工具,使得开发者可以构建能够充分利用多核处理器性能的应用程序。本书详细介绍了这些主题,并提供了实例代码和实践建议。 首先,书中详细讨论了Java线程的创建...

    java并发编程书籍

    2. **同步机制**:Java并发编程的核心在于同步,以防止数据不一致性和资源竞争。`synchronized`关键字用于实现临界区的互斥访问,确保同一时刻只有一个线程执行特定代码块。此外,还有`wait()`, `notify()`, `...

    java并发编程与实践

    "Java并发编程与实践"文档深入剖析了这一主题,旨在帮助开发者理解和掌握如何在Java环境中有效地实现并发。 并发是指在单个执行单元(如CPU)中同时执行两个或更多任务的能力。在Java中,这主要通过线程来实现,...

    java并发编程

    5. **ReentrantLock**: 这是可重入的互斥锁,比`synchronized`关键字更灵活,支持公平锁和非公平锁,以及可中断和定时等待。 6. **Atomic* 类**: 如AtomicInteger、AtomicLong等,提供了原子操作,保证在并发环境下...

    基于Java并发编程的多线程同步与锁机制.zip

    基于Java并发编程的多线程同步与锁机制 项目简介 本项目旨在深入探讨Java并发编程中的多线程同步与锁机制,涵盖了从基础的线程创建、同步方法到高级的并发工具类如ReentrantLock、ReadWriteLock、Atomic类等的...

    java并发实战中文文档

    3. **锁**:Java并发库中的`java.util.concurrent.locks`包提供了更高级的锁机制,如可重入锁(`ReentrantLock`)、读写锁(`ReadWriteLock`)和条件变量(`Condition`),这些工具允许更灵活的控制并发访问。 4. **并发...

    JAVA并发编程实践

    Java并发编程是Java高级特性之一,它允许开发者编写能够同时执行多个任务的程序,这对于提高应用程序的性能至关重要。下面将详细探讨Java并发编程中的关键概念、技术及实践技巧。 ### 一、Java并发编程基础 #### ...

    ( Java并发程序设计教程.zip )高清版 PDF

    《Java并发程序设计教程》是一本深入探讨Java平台上的并发编程技术的专业书籍。并发和多线程是现代软件开发中的核心概念,特别是在Java这样的多线程支持强大的编程语言中。这本书详细介绍了如何在Java环境中有效地...

    java并发编程实战高清版pdf

    Java并发编程涉及到许多关键概念,如线程、同步、锁、并发容器、原子变量以及并发工具类等。以下是一些主要的知识点: 1. **线程基础**:线程是程序执行的最小单位,Java中的`Thread`类提供了创建和管理线程的方法...

    Java并发编程常识-梁飞.rar

    Java并发编程的核心组件包括线程、锁、同步、并发集合和并发工具类。线程是并发的基本执行单元,Java提供了Thread类来创建和控制线程。锁用于在多线程环境下控制共享资源的访问,Java提供了synchronized关键字和java...

Global site tag (gtag.js) - Google Analytics