1、 wait和sleep的区别:(面试题)
1、 sleep指定时间,wait可以指定时间,也可以不用指定时间。
2、 wait方法必须定义在同步中,sleep方法不一定。
3、 在同步中wait sleep对于执行权和锁的处理不同:
i. Sleep释放CPU执行权,但是没有释放锁。
ii. Wait释放执行权、释放锁。
实现代码:
Public void run()
{
Synchronized(this)
{
Code…sleep(10);//此线程进入冻结状态,释放了执行权,并没有释放锁。
Wait();//等待状态下,释放执行权、释放锁,因为它需要被对象唤醒,所以要释放锁
}
}
Public void method()
{
Synchronized(this)
{
notifyAll();//唤醒上面所有的线程。但是此时t0、t1并没有执行,因为锁还在此线程中,只有当它执行完毕之后,释放锁。它们获取锁之后才有机会执行。
}
}
2、 停止线程:
1、 Stop方法已经过时,为什么?因为该方法具有不固定的安全性。
如何停止线程?
只有一种方法:
线程执行的代码结束,线程会自动终止。
1、 run方法中通常有循环,所以只要循环结束即可。所以只要控制循环条件。最简单的方式就是定义标记。
2、 如果run中有同步可以让线程出现冻结状态的方法,比如wait那么线程就不会去读取标记。这时必须让线程恢复到运行状态才可以有机会读取到标记,所以通过正常的恢复方法比如notify、sleep时间到,但是如果没有办法正常恢复,就必须使用强制手段,interrupt方法,强制将线程的冻结状态清除,让线程恢复运行。其实就是让线程重新获取读取标记、结束。但是别忘了强制动作会产生异常要处理。
实现代码:
StopThreadDemo.java
class StopThread implements Runnable
{
private boolean flag=true;//定义标记控制住循环。
public synchronized void run()
{
while(flag)//开始true、此时定义标记控制循环。
{
try
{
wait();//当存在同步时,wait方法不会让线程去读取标记。此时主线程结束了,但是这两个线程却在这里等待了。并没有结束。
}
catch (InterruptedException e)
{
System.out.println(Thread.currentThread().getName()+"....Exception");
setFlag();//如果发生了强制中断,只要把状态切断到假。
}
System.out.println(Thread.currentThread().getName()+"...");
}
}
public void setFlag()
{
flag=false;
}
}
class StopThreadDemo
{
public static void main(String[] args)
{
StopThread st=new StopThread();
Thread t1=new Thread(st);
Thread t2=new Thread(st);
t1.start();
t2.setDaemon(true);//标记成了守护线程。
t2.start();
for(int x=0; ;x++)
{
if(x==50)
{
st.setFlag();
t1.interrupt();//t1将它的冻结状态强制结束。
t2.interrupt();//中断方法。其实不是中断线程。而且还抛出了异常。
//其实会将冻结中的线程强行恢复到运行状态,就会读到标记。这就是中断线程。并不是结束线程。一定要注意要区分。
//
break;
}
System.out.println (Thread.currentThread().getName()+"....");
}
System.out.println("Hello World!");
}
}
3、守护线程:setDaemon();
线程标记,守护线程,当正在运行的线程是守护线程时,JVM自动退出,该方法在开启之前调用,也就是说在start方法之前调用。
线程分两种:
前台线程:自己创建的线程都是前台线程。
后台线程:一旦调用了此方法为守护线程之后的线程都是守护线程。
区别:都是线程,启动后都再抢夺CPU的执行权,这里是没有区别的,最大的区别就是如果线程结束了,正在运行的后台线程也随着结束,简单的说后台线程是以来前台线程而执行的。
4、线程细节:
1、join:当A线程执行到B线程时,那么A线程就会等待,等B执行完毕,A才会执行。
代码实现:
D1.join();d1加入,说明了主线程必须先释放执行权给它,等到d1结束之后主线程才恢复执行状态,所以输出结果是等d1全部都执行完毕之后,才有其他线程的交替执行。
记住:谁把执行权给了谁,就只和给的对象的执行权有关,等它结束之后,就会重新获取执行
记住:主线程是因为谁放弃了执行权,就只和那个线程有关系权,与其他线程无关。
2、优先级:代表抢夺资源的频率。有两种方法:getPriority setPriority来获取优先级和设置优先级,只有十个数字可以使用1-10这十个数字,同时线程中提供了几个特殊的方法:
线程类中提供了MAX_PRIORITY MIN_PRIORTY NORM_PRIORTY。
3、yield:结束该线程,释放执行权。
4、toString();获取线程详细信息,包括线程组、线程名、所属线程。
实现代码:ThreadMethodDemo.java
5、string类:
1、字符串的特点:
1、java中用String类来描述字符串。
2、字符串是一个特殊的对象,一旦初始化就不可以被改变,因为是常量。
面试题1:
String s="abc";
String s1=new Strng("abc");是否相同?
前者"abc"是一个对象。后者是两个对象,new string()代表一个对象,"abc"也代表一个对象。
Sop(s1==s2);==比较的是数据。false
Sop(s1.equals(s2));比较的是内存的地址值,equals覆写了Object类中的equals方法。
True
面试题2:
String a="abcd";//在缓冲池创建了一个abcd的字符串。
String a1="ab";//a1和a2都是变量,无法确定。
String a2="cd";
String b=a1+a2;//b是要重新进行分配的。
String c="ab"+"cd";//两个都是常量值,用连接符连接在一起还是字符创。abcd
System.out.println("a==b:"+(a==b));//false
System.out.println("a==c:"+(a==c));//true
2、常见操作方法:
1、获取:
a) 获取长度:
Int length();数组长度是个属性,字符串是个方法
b) 获取字符串中的字符:
charAt(int index);返回值是一个字符。
c) 一个字符或者一个字符串在一个字符串中的位置
Int indexof(int ch)
Int indexof(int ch,int fromIndex)
Int indexof(ch,fromIndex)
Int indexof(srting,fromindex)
Int lastIndexof(ch);
注意:这些获取索引位的方法,如果没有查找的内容,返回-1,所以这个方法。
d) 获取部分字符串:
String substring(begin,end)
2、判断:
a) 是否包含指定的字符串
Boolean contains(String)
b) 是否是以指定的字符串开头
Boolean startsWith(String)
c) 是否是以指定的字符串结尾
Boolean endwith(String)
d) 忽略大小写判断字符串
Boolean equalsIgnoreCase(string)
3、转换:
a) 将字符串转成大小写
String toLowerCase();
String toUpperCase();
b) 将字符串转成数组
Byte[] getBytes();
Char[] getChar();
c) 将字符串转成字符串数组
String[]
d) 将字符串中的内容进行替换
String replace(oldch1,new ch2)
String replace(string1,string2)
e) 去除字符串两端的空白
Trim();
如何查阅API文档的小技巧,先查找返回值类型,缩小查找范围。
实现代码:
ublic static void main(String[] args) {
// stringMethod4();
String str = " ab c ";
System.out.println("-"+str.trim()+"-");
String s = String.valueOf(4);
System.out.println(4+"");
System.out.println("ab"+"cd");
System.out.println("ab".concat("cd"));
}
private static void stringMethod4() {
String str = "lisi.wangwu.zhaoliu";
String[] strs = str.split("\\.");
for (int i = 0; i < strs.length; i++) {
System.out.println(strs[i]);
}
str = "hello";
String s = str.replace('a', 'k');
System.out.println("s="+s);
System.out.println(str);
}
private static void stringMethod3() {
String str = "aBCd";
String s = str.toLowerCase();
System.out.println(s);
String s1 = str.toUpperCase();
System.out.println(s1);
System.out.println(str);
char[] arr = str.toCharArray();
for(int x = 0; x<arr.length; x++){
System.out.println(arr[x]);
}
}
private static void stringMethod2() {
String str = "ThreadDemo.java";
System.out.println("contains(Demo):"+str.contains("Demo"));
System.out.println("starsWith(Thread):"+str.startsWith("Thread"));
System.out.println("endsWith(.java):"+str.endsWith(".java"));
System.out.println("isEmpty:"+str.isEmpty());
str = "abc";说
System.out.println(str.equalsIgnoreCase("abC"));
}
private static void stringMethod() {
String str = "abcdaef";
System.out.println("length;"+str.length());
System.out.println("charAt(2):"+str.charAt(2));
System.out.println("indexOf(a):"+str.indexOf('a',2));
System.out.println("lastIndexOf(a):"+str.lastIndexOf('k'));
System.out.println("substring(1,3):"+str.substring(0,str.length()));
}
|
|