线程阻塞

java多线程总结三:sleep()、join()、interrupt()示例

佐手、 提交于 2020-03-28 03:44:11
这是一个来自《java编程思想上的示例》 [java] view plain copy package demo.thread; /** *sleep()是静态方法,是属于类的,作用是让当前线程阻塞 *join()是使线程同步,如在某个线程里调用t.join()表示t线程执行完再执行当前线程 *interrupt()给线程设定一个标志表示该线程已被中断,但在异常捕获时将清理这个标志 *所以在catch子句中,该标志为false */ public class SleepJoinDemo { public static void main(String[] args) { Sleeper sleep1 = new Sleeper( "sleep1", 1500); Sleeper sleep2 = new Sleeper( "sleep2", 1500); Joiner join1 = new Joiner( "join1", sleep1); Joiner join2 = new Joiner( "join2", sleep1); sleep2.interrupt(); } } class Sleeper extends Thread { // 可以传参设定睡眠时间 private int sleepTime; public Sleeper(String name, int

Java关键字-synchronized

时光毁灭记忆、已成空白 提交于 2020-03-28 03:08:43
synchronized 关键字的三种使用方式   修饰实例方法,作用于当前对象实例加锁,进入同步代码前要获得当前对象实例的锁。   修饰静态方法,作用于当前类对象加锁,进入同步代码前要获得当前类对象的锁 。也就是给当前类加锁,会作用于类的所有对象实例,因为静态成员不属于任何一个实例对象,是类成员( static 表明这是该类的一个静态资源,不管new了多少个对象,只有一份,所以对该类的所有对象都加了锁)。所以如果一个线程A调用一个实例对象的非静态 synchronized 方法,而线程B需要调用这个实例对象所属类的静态 synchronized 方法,是允许的,不会发生互斥现象,因为访问静态 synchronized 方法占用的锁是当前类的锁,而访问非静态 synchronized 方法占用的锁是当前实例对象锁。   修饰代码块,指定加锁对象,对给定对象加锁,进入同步代码库前要获得给定对象的锁。 和 synchronized 方法一样,synchronized(this)代码块也是锁定当前对象的。synchronized 关键字加到 static 静态方法和 synchronized(class)代码块上都是是给 Class 类上锁。需要注意的是:尽量不要使用 synchronized(String a) 因为JVM中,字符串常量池具有缓冲功能! synchronized

线程中断方法interrupt() 与 cancel()

爷,独闯天下 提交于 2020-03-27 22:19:32
(一).关于interrupt() interrupt()并不直接中断线程,而是设定一个中断标识,然后由程序进行中断检查,确定是否中断。 1. sleep() & interrupt() 线程A正在使用sleep()暂停着: Thread.sleep(100000); 如果要取消他的等待状态,可以在正在执行的线程里(比如这里是B)调用a.interrupt(); 令线程A放弃睡眠操作,这里a是线程A对应到的Thread实例执行interrupt()时,并不需要获取Thread实例的锁定.任何线程在任何时刻,都可以调用其他线程interrupt().当sleep中的线程被调用interrupt()时,就会放弃暂停的状态.并抛出InterruptedException.丢出异常的,是A线程. 2. wait() & interrupt() 线程A调用了wait()进入了等待状态,也可以用interrupt()取消. 不过这时候要小心锁定的问题.线程在进入等待区,会把锁定解除,当对等待中的线程调用interrupt()时(注意是等待的线程调用其自己的interrupt()),会先重新获取锁定,再抛出异常.在获取锁定之前,是无法抛出异常的. 3. join() & interrupt() 当线程以join()等待其他线程结束时,一样可以使用interrupt()取消之.因为调用join(

Java Thread(线程)案例详解sleep和wait的区别

自作多情 提交于 2020-03-27 18:16:54
Java Thread(线程)案例详解sleep和wait的区别 上次对Java Thread有了总体的概述与总结,当然大多都是理论上的,这次我将详解Thread中两个常用且容易疑惑的方法、并通过实例代码进行解疑。。。 F 区别 sleep()方法   sleep()使当前线程进入停滞状态(阻塞当前线程),让出CUP的使用、目的是不让当前线程独自霸占该进程所获的CPU资源,以留一定时间给其他线程执行的机会;    sleep()是Thread类的Static(静态)的方法;因此他不能改变对象的机锁,所以当在一个Synchronized块中调用Sleep()方法是,线程虽然休眠了,但是对象的机锁并木有被释放,其他线程无法访问这个对象(即使睡着也持有对象锁)。   在sleep()休眠时间期满后,该线程不一定会立即执行,这是因为其它线程可能正在运行而且没有被调度为放弃执行,除非此线程具有更高的优先级。    wait()方法   wait()方法是Object类里的方法;当一个线程执行到wait()方法时,它就进入到一个和该对象相关的等待池中,同时失去(释放)了对象的机锁(暂时失去机锁,wait(long timeout)超时时间到后还需要返还对象锁);其他线程可以访问;   wait()使用notify或者notifyAlll或者指定睡眠时间来唤醒当前等待池中的线程。   wiat(

java多线程解读一(基础篇)

允我心安 提交于 2020-03-27 17:32:42
一、线程的定义 每个应用程序内部都是由一个或多个的进程组成,而每个进程内部都是由许多具体的线程执行,所以,线程是每个程序执行的最小单位。 二、线程的实现 1.通过继承java.lang.Thread类、重写类中的run方法 class PrimeThread extends Thread {   long minPrime;   PrimeThread(long minPrime) {     this.minPrime = minPrime;   }   public void run() {      // compute primes larger than minPrime . . .   } } 然后通过创建线程对象,使线程就绪 PrimeThread p = new PrimeThread(143); p.start(); 2.通过实现java.lang.Runnable接口,实现类中的run方法 class PrimeRun implements Runnable {   long minPrime;   PrimeRun(long minPrime) {     this.minPrime = minPrime;   }   public void run() {     // compute primes larger than minPrime . . .   

多线程之wait,notify,volatile,synchronized,sleep

浪尽此生 提交于 2020-03-27 17:32:08
  最近在学习多线程,现在进行总结一下吧。首先要了解一下以下几个名词。   (1)wait:当线程调用wait()方法时,当前该线程会进入阻塞状态,且 释放锁 ,使用wait方法的时候, 必须配合synchronized使用 。   (2)notify:当线程调用notify()方法时,会唤醒一个处于等待该对象锁的线程, 不释放锁 ,使用notify方法的时候, 必须配合synchronized使用 。   (3)sleep:当线程调用sleep()方法时,会让出CPU执行权, 不释放锁 。当指定的时间到了后,会自动恢复运行状态。   (4)volatile:可见性,它修饰的成员变量在每次被线程访问时,都强迫从内存中重读该成员变量的值;而且,当成员变量发生变化时,强迫线程将变化值回写到共享内存,这样在任何时刻两个不同线程总是看到某一成员变量的同一个值,这就是保证了可见性。( 当多个线程操作同一个成员变量的时候,为了提高效率,JVM为每个线程单独复制了一份 ,这样会导致各个线程读取的数据出现脏数据,所以使用volatile关键字可以解决脏数据问题)。   (5)synchronized:synchronized为一段操作或内存进行加锁,它具有互斥性。当线程要操作被synchronized修饰的内存或操作时, 必须首先获得锁才能进行后续操作

Java 一些面试题(未完待续)

依然范特西╮ 提交于 2020-03-27 16:57:29
计算机网络 面试基础知识之计算机网络 基础知识 集合框架 多线程 Thread类的sleep()方法和对象的wait()方法都可以让线程暂停执行,它们有什么区别? leep()方法(休眠)是线程类(Thread)的静态方法,调用此方法会让当前线程暂停执行指定的时间, 将执行机会(CPU)让给其他线程,但是对象的锁依然保持,因此休眠时间结束后会自动恢复(线程回到就绪状态)。 wait()是Object类的方法,调用对象的wait()方法导致当前线程放弃对象的锁(线程暂停执行),进入对象的等待池(wait pool),只有调用对象的notify()方法(或notifyAll()方法)时才能唤醒等待池中的线程进入等锁池(lockpool),如果线程重新获得对象的锁就可以进入就绪状态 线程的sleep()方法和yield()方法有什么区别? ① sleep()方法给其他线程运行机会时不考虑线程的优先级,因此会给低优先级的线程以运行的机会;yield()方法只会给相同优先级或更高优先级的线程以运行的机会; ② 线程执行sleep()方法后转入阻塞(blocked)状态,而执行yield()方法后转入就绪(ready)状态; ③ sleep()方法声明抛出InterruptedException,而yield()方法没有声明任何异常; ④ sleep()方法比yield()方法

试题

牧云@^-^@ 提交于 2020-03-27 03:29:55
讲一讲并行和并发 进程的线程的区别 进程是资源分配的最小单位,线程是程序执行的最小单位。 进程有自己的独立地址空间,每启动一个进程,系统就会为它分配地址空间,建立数据表来维护代码段、堆栈段和数据段,这种操作非常昂贵。而线程是共享进程中的数据的,使用相同的地址空间,因此CPU切换一个线程的花费远比进程要小很多,同时创建一个线程的开销也比进程要小很多。 线程之间的通信更方便,同一进程下的线程共享全局变量、静态变量等数据,而进程之间的通信需要以通信的方式(IPC)进行。不过如何处理好同步与互斥是编写多线程程序的难点。 但是多进程程序更健壮,多线程程序只要有一个线程死掉,整个进程也死掉了,而一个进程死掉并不会对另外一个进程造成影响,因为进程有自己独立的地址空间。 进程间通信的有哪几种方式 管道(Pipe)及有名管道(named pipe): 信号量 共享内存 信号(Signal) 报文(Message)队列(消息队列) 套接字 线程间资源可以共享吗,进程间呢 Java并发,说一说了解哪些,volatie个synchronized的 volatile本质是告诉JVM当前变量在寄存器中的值是不确定的,需要从主存中读取。synchronized则是锁定当前变量,只有当前线程可以访问该变量,其它线程被阻塞。 volatile仅能使用在变量级别,synchronized则可以使用在变量、方法。

如何优雅地中止线程?

不羁的心 提交于 2020-03-27 01:46:14
3 月,跳不动了?>>> 本文来学习如何学习优雅地中止线程?通过 Java 线程的生老病死 的学习,我相信大家对线程的运行以及线程的状态有一定了解了,那么我们现在来学习中止线程: 错误的线程中止 - stop 首先来讲解一个错误的方式来中止线程 — stop :中止线程,并且清除监控器锁的信息,但是可能导致线程安全问题,JDK 不建议使用,类似的方法还有 destory,由于 JDK 从未实现该方法,在这里就不介绍了。 接下来通过一段程序来讲解为什么 stop 会导致线程安全问题? 首先定义一个线程类 StopThread : public class StopThread extends Thread { private int i = 0; private int j = 0; @Override public void run() { synchronized (this) { // 增加同步锁,确保线程安全 ++i; try { // 休眠10秒,模拟耗时操作 Thread.sleep(10000); } catch (InterruptedException e) { e.printStackTrace(); } ++j; } } /** * 打印 i 和 j */ public void print() { System.out.println("i=" + i + "

Java Map

拥有回忆 提交于 2020-03-26 18:55:30
Map无论在Java编程或者面试中,都占用很重要的地位,这里试图聊聊相关的概念,看看是否能够理清楚相关的思路。 HashMap HashMap 是我们经常会用到的集合类,JDK 1.7 之前底层使用了数组加链表的组合结构,如下图所示: 新添加的元素通过取模的方式,定位 Table 数组位置,然后将元素加入链表头部,这样下次提取时就可以快速被访问到。 访问数据时,也是通过取模的方式,定位数组中的位置,然后再遍历链表,依次比较,获取相应的元素。 如果 HasMap 中元素过多时,可能导致某个位置上链表很长。原本 O(1) 查找性能,可能就退化成 O(N) ,严重降低查找效率。 为了避免这种情况,当 HasMap 元素数量满足以下条件时,将会自动扩容,重新分配元素。 1// size:HashMap 中实际元素数量 2//capacity:HashMap 容量,即 Table 数组长度,默认为:16 3//loadFactor:负载因子,默认为:0.75 4 size>=capacity*loadFactor HasMap 将会把容量扩充为原来的两倍,然后将原数组元素迁移至新数组。 1void transfer(Entry[] newTable, boolean rehash) { 2 int newCapacity = newTable.length; 3 for (Entry<K,V