1.守护线程
Java线程分为用户线程和守护线程。
守护线程是程序运行的时候在后台提供一种通用服务的线程。所有用户线程停止,进程会停掉所有守护线程,退出程序。
java中把线程设置为守护线程的方法:在 start 线程之前调用线程的 setDaemon(true) 方法。
注意:
setDaemon(true) 必须在 start() 之前设置,否则会抛出IllegalThreadStateException异常,该线程仍默认为用户线程,继续执行
守护线程创建的线程也是守护线程
package mythread;
public class MyThread extends Thread{
@Override
public void run(){
for(int i=0;i<100;i++){
System.out.println(i);
}
}
}
package mythread;
/*
* void setDaemon(boolean on):将此线程标记为守护线程,当运行的程序都是守护线程时,Java虚拟机将退出
* */
public class ThreadDaemonTest {
public static void main(String[] args) {
MyThread td1 = new MyThread();
MyThread td2 = new MyThread();
td1.setName("关羽");
td2.setName("张飞");
Thread.currentThread().setName("刘备");
td1.setDaemon(true);
td2.setDaemon(true);
td1.start();
td2.start();
for(int i=0;i<10;i++){
System.out.println(Thread.currentThread().getName()+":"+i);
}
}
}
2. void join():等待线程死亡
package mythread;
public class ThreadJoinDemo {
public static void main(String[] args) {
ThreadJoin ii1= new ThreadJoin();
ThreadJoin ii2= new ThreadJoin();
ThreadJoin ii3= new ThreadJoin();
ii1.setName("康熙");
ii2.setName("四阿哥");
ii3.setName("八阿哥");
ii1.start();
try {
ii1.join();//等到这个线程死亡
} catch (InterruptedException e) {
e.printStackTrace();
}
ii2.start();
ii3.start();
}
}
3.sleep() 和 wait() 有什么区别
1)static void sleep(long millis):使当前正在执行的线程的停留指定的毫秒数,不释放对象锁,休眠时间到自动苏醒继续执行
wait() 方法导致当前线程等待,直到另一个线程调用该对象的notify()方法或者notifyAll()方法
2)sleep() 是 Thread 类的静态本地方法;wait() 是Object类的成员本地方法
3)sleep() 方法可以在任何地方使用;wait() 方法则只能在同步方法或同步代码块中使用,否则抛出异常Exception in thread “Thread-0” java.lang.IllegalMonitorStateException
package mythread;
public class Box {
private int milk;
private boolean state = false;//奶箱的状态
public synchronized void put(int milk){
//如果有牛奶,就等待消费
if(state){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//如果没有牛奶,就生产牛奶
this.milk=milk;
System.out.println("送奶工将第"+this.milk+"瓶牛奶放入奶箱");
state=true;
notifyAll();
}
public synchronized void get(){
//如果没有牛奶,就等待生产
if(!state){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//如果有牛奶,就取牛奶
System.out.println("取第"+this.milk+"瓶牛奶");
state=false;
notifyAll();
}
}
package mythread;
public class Producer implements Runnable{
private Box box;
public Producer(Box box){
this.box=box;
}
@Override
public void run(){
for(int i=1;i<5;i++){
box.put(i);
}
}
}
package mythread;
public class Consumer implements Runnable{
private Box box;
public Consumer(Box box){
this.box=box;
}
@Override
public void run(){
while (true){
box.get();
}
}
}
package mythread;
public class BoxDemo {
public static void main(String[] args) {
Box box1= new Box();
Producer p = new Producer(box1);
Consumer s = new Consumer(box1);
Thread t1= new Thread(p);
Thread t2= new Thread(s);
t1.start();
t2.start();
}
}
输出结果:
送奶工将第1瓶牛奶放入奶箱
取第1瓶牛奶
送奶工将第2瓶牛奶放入奶箱
取第2瓶牛奶
送奶工将第3瓶牛奶放入奶箱
取第3瓶牛奶
送奶工将第4瓶牛奶放入奶箱
取第4瓶牛奶
4.给定两个字符串形式的非负整数 num1 和num2 ,计算它们的和,并以字符串输出。
package lamdba;
public class MuiltyTest {
public static void main(String[] args) {
String result = multiply("127","33");
System.out.println(result);
}
private static String multiply(String str1,String str2) {
if (str1.equals("0") || str2.equals("0")) {
return "0";
}
if((str1.length()==0 || str1 ==null)||(str2.length()==0 || str2 ==null)){
return "0";
}
if(!checkDigtal(str1) ||!checkDigtal(str2)){
return "0";
}
int len1 = str1.length();
int len2 = str2.length();
int[] num = new int[len1 + len2];
for (int i = len1 - 1; i >= 0; i--) {
int t = str1.charAt(i) - '0';
for (int j = len2 - 1; j >= 0; j--) {
int sum = t * (str2.charAt(j) - '0');
num[i + j + 1] += sum % 10;
num[i + j] += (sum / 10 + num[i + j + 1] / 10);
num[i + j + 1] %= 10;
}
}
StringBuilder sb = new StringBuilder("");
int k = 0;
//去除前导0
while (num[k] == 0 && k < len1 + len2) {
k++;
}
for (; k < len1 + len2; k++) {
sb.append(num[k]);
}
return sb.toString();
}
public static boolean checkDigtal(String str) {
for (int i = 0; i < str.length(); i++) {
if (!Character.isDigit(str.charAt(i))) {
return false;
}
}
return true;
}
}
5.给定一个未排序的整数数组,找出最长连续序列的长度
package lamdba;
import java.util.HashSet;
//输入:[8,1,9,3,2,4],那么其最长连续序列是[1,2,3,4],即输出长度为4
public class SequenceTest {
public static void main(String[] args) {
int[] nums={8,1,9,3,2,4,6,5};
System.out.println("最长连续序列:"+longSequence(nums));
}
private static int longSequence(int[] nums) {
int max = 0;
if (nums == null || nums.length == 0) {
return 0;
}
HashSet<Integer> set = new HashSet<Integer>();
for (int i : nums) {
set.add(i);
}
for (int num : nums) {
if (!set.contains(num - 1)) {
int val = num;
while (set.remove(val++)) {
max = Math.max(max, val - num);
}
}
}
return max;
}
}
6.给定一个只包含 ‘(’ 和 ‘)’ 的字符串,找出最长的包含有效括号的子串的长度
package learn;
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/*
* 找出最长的包含有效括号的字串的长度
* */
public class MachTest {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String str = sc.nextLine();
System.out.println("最长的包含有效括号的字串的长度:"+stringLength(str));
}
public static int stringLength(String str){
int length=0;
if(str.isEmpty()){
return length;
}
Pattern p = Pattern.compile("\\(\\){1,}");
Matcher m = p.matcher(str);
while (m.find()){
length=m.group().length();
}
return length;
}
}
7.查找字符串中第一次重复的字符
package lamdba;
/*
* java小算法—查找字符串中第一次重复的字符
* */
public class StringTest {
public static void main(String[] args) {
String str ="fdsfsdfsdfd";
int p = find(str);
System.out.println("字符串中第一次重复的字符是:"+str.charAt(p));
}
public static int find(String str){
int position = -1;
for(int i=0;i<str.length();i++){
char c = str.charAt(i);
if(str.indexOf(c,i+1) !=-1){
position=i;
break;
}
}
return position;
}
}
8.乱序数组排序,将正数都放在负数的左边
待编写
9.TCP和UDP的区别应用
区别:
面向连接vs无连接:tcp三次握手四次挥手建立连接;udp无需建立连接,可以直接发起
可靠vs不可靠:tcp采用握手、ack和重传机制,实现可靠传输
面向字节流vs面向报文
TCP应用场景:
效率要求相对低,但对准确性要求相对高的场景,因为传输中需要对数据进行确认,重发,排序等操作,效率没有udp高
文件传输:FTP\HTTP对数据的准确性要求高,速度可以相对慢
发送或接收邮件:POP3\IMAP\SMTP对数据准确性要求高,非紧急应用
远程登陆:TELNET\SSH对数据准确性有一定要求,有连接概念
UCP应用场景
即时通信:QQ聊天,对数据准确性和丢包要求比较低,但速度必须快
在线视频:RTSP速度一定要快,保证视频连续,但是偶尔花了一个图像帧,还是可以接受的
网络语音电话:VoIP数据包一般比较小,需要高速发送,偶尔断音或串音也没有问题