加同步,解决安全问题;效率高吗?不高;怎样解决?通过双重判断的形式解决。
//懒汉式:延迟加载方式。 当多线程访问懒汉式时,因为懒汉式的方法内对共性数据进行多条语句的操作。所以容易出现线程安全问题。为了解决,加入同步机制,解决安全问题。但是却带来了效率降低。
为了效率问题,通过双重判断的形式解决。 class Single{
private static Single s = null; private Single(){}
public static Single getInstance(){ //锁是谁?字节码文件对象; if(s == null){
synchronized(Single.class){ if(s == null)
s = new Single(); } }
return s; } }
---------------------------------------------------------
同步死锁:通常只要将同步进行嵌套,就可以看到现象。同步函数中有同步代码块,同步代码块中还有同步函数。
线程间通信:思路:多个线程在操作同一个资源,但是操作的动作却不一样。 1:将资源封装成对象。
2:将线程执行的任务(任务其实就是run方法。)也封装成对象。
等待唤醒机制:涉及的方法:
wait:将同步中的线程处于冻结状态。释放了执行权,释放了资格。同时将线程对象存储到线程池中。
notify:唤醒线程池中某一个等待线程。 notifyAll:唤醒的是线程池中的所有线程。
注意:
1:这些方法都需要定义在同步中。 2:因为这些方法必须要标示所属的锁。
你要知道 A锁上的线程被wait了,那这个线程就相当于处于A锁的线程池中,只能A锁的notify唤醒。
3:这三个方法都定义在Object类中。为什么操作线程的方法定义在Object类中? 因为这三个方法都需要定义同步内,并标示所属的同步锁,既然被锁调用,而锁又可以是任意对象,那么能被任意对象调用的方法一定定义在Object类中。
wait和sleep区别: 分析这两个方法:从执行权和锁上来分析:
wait:可以指定时间也可以不指定时间。不指定时间,只能由对应的notify或者notifyAll来唤醒。
sleep:必须指定时间,时间到自动从冻结状态转成运行状态(临时阻塞状态)。 wait:线程会释放执行权,而且线程会释放锁。 Sleep:线程会释放执行权,但不是不释放锁。
线程的停止:通过stop方法就可以停止线程。但是这个方式过时了。
停止线程:原理就是:让线程运行的代码结束,也就是结束run方法。
怎么结束run方法?一般run方法里肯定定义循环。所以只要结束循环即可。 第一种方式:定义循环的结束标记。 第二种方式:如果线程处于了冻结状态,是不可能读到标记的,这时就需要通过Thread类中的interrupt方法,将其冻结状态强制清除。让线程恢复具备执行资格的状态,让线程可以读到标记,并结束。
---------< java.lang.Thread >---------- interrupt():中断线程。
setPriority(int newPriority):更改线程的优先级。 getPriority():返回线程的优先级。
toString():返回该线程的字符串表示形式,包括线程名称、优先级和线程组。 Thread.yield():暂停当前正在执行的线程对象,并执行其他线程。
setDaemon(true):将该线程标记为守护线程或用户线程。将该线程标记为守护线程或用户线程。当正在运行的线程都是守护线程时,Java 虚拟机退出。该方法必须在启动线程前调用。
join:临时加入一个线程的时候可以使用join方法。
当A线程执行到了B线程的join方式。A线程处于冻结状态,释放了执行权,B开始执行。A什么时候执行呢?只有当B线程运行结束后,A才从冻结状态恢复运行状态执行。
8.下面程序被编译运行时,下面哪些描述是正确的______C___。 class B{
public int f(int i){ return i+i; }
public int f(int i, int j){ return i+j; }
public int f(char c){ return c; } }
public class Test extends B{ public int f(int i, int j){ return super.f(i,j); }
public int f(int j){ return -j; }
public static void main(String[] args){ B x = new Test();
System.out.println(x.f(5,10)+” “+x.f(4)+” “+x.f(‘A’)); } }
A.编译不通过,B x = new Test() 出错,类型不匹配
B.编译不通过,原因是B.f(char c),一个char类型不能直接当做int类型返回 C.编译通过,运行输出结果是15 -4 65 D.编译通过,运行输出结果是15 8 65
9.下面哪个类或接口定义了wait()、notify()、notifyAll()方法___C____ A.java.lang.Thread B.java.lang.Runnable C.java.lang.Object D.java.lang.TreadGroup
10.在Java API文档中,下面的哪部分未被包括在内__D_____ A.类的用途的描述 B.类层次
C.父类方法的列表 D.成员变量的列表
11.下面列出的修饰符中,哪一个用来修饰方法(method)要求此方法必须显式地获得某个对象才能执行____B____ A.final
B.synchronized C.static D.public
12.下面的各种异常中,哪种异常在一个方法中没有声明抛出此异常时也可以在其方法体中直接抛出_____D___
A.java.lang.ClassNotFoundException
B.java.lang.Exception
C.java.lang.NullPointerException D.java.ioException
二、 多选题(共5题,每题3分,共15分)
1.下面对操作系统中线程和进程的表述有错误的是___BD____
A.进程是程序的运行实例,它包含内存和资源,而线程是由进程进一步派生出来的一组代码的执行过程
B.每个进程都有一个主线程,还可以建立另外的线程。进程中的线程是并行执行的,每个线程占用CPU的时间由此进程来调度。
C.进程中的所有线程共享进程的虚拟地址空间,这意味着所有线程都可以访问进程的全局变量和资源。
D.进程中的每个线程的声明周期都在该进程中,每个线程都有自己的私有虚拟地址空间。
2.下面关于HashMap与Hashtable区别的表述正确的是__ABC____ A.HashMap与Hashtable采用的hash/rehas算法基本一致。
B.HashMap允许将null作为一个entry得key或value,而Hashtable不允许。 C.HashMap与Hashtable都是Map interface的实现。
D.Hashtable的方法是syncronized的,而HashMap不是,因此HashMap非线程安全 //--Hashtable:底层是哈希表数据结构,是线程同步的。不可以存储null键,null值。 |--HashMap:底层是哈希表数据结构,是线程不同步的。可以存储null键,null值。替代了Hashtable.
Map集合: