文章目录
0.单例 在多线程里会怎样?
//懒汉式
/*class Single{
private static Single single;// null
private Single() {}
synchronized public static Single getInstance() {
if(single == null) {
single = new Single();
}
return single;
}
}*/
// 饿汉
/*class Single{
private static Single single = new Single();
private Single() {}
synchronized public static Single getInstance() {
return single;
}
}*/
// 最佳
class Single{
// 静态内部类
private static class SingleInstance{
private static Single single = new Single();// 加载初始化
}
public static Single getInstance() {
return SingleInstance.single;//返回对象
}
}
public class TestSingle {
public static void main(String[] args) throws ClassNotFoundException {
new Thread(new Runnable() {
public void run() {
System.out.println(Single.getInstance());// 对象信息
}
}).start();
new Thread(new Runnable() {
public void run() {
System.out.println(Single.getInstance());// 对象信息
}
}).start();
/* Single single1 = Single.getInstance();
Single single2 = Single.getInstance();
System.out.println(single1);//
System.out.println(single2);//
*/
}
}
答:都不好,最佳的如上所示
1.死锁
class Zhangsan{
public void say() {
System.out.println("你给我书,我就给你画");
}
public void get() {
System.out.println("张三获得了书");
}
}
class Lisi{
public void say() {
System.out.println("你给我画,我就给你书");
}
public void get() {
System.out.println("李四获得了画");
}
}
class Thread1 implements Runnable{
//
private static Zhangsan zhangsan = new Zhangsan();
private static Lisi lisi = new Lisi();
// 定义boolean
public boolean tag = false;
public void run() {//zhangsan lisi
if(tag == true) {// 张三
synchronized (zhangsan) {// zhangsan
zhangsan.say();// 说
try {
Thread.sleep(1000); // 休息
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (lisi) {
zhangsan.get();
}
}
}else {//李四
try {
Thread.sleep(5000);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
synchronized (lisi) {// lisi
lisi.say();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (zhangsan) {
lisi.get();
}
}
}
}
}
public class TestLock {
public static void main(String[] args) {
Thread1 td1 = new Thread1();
td1.tag = true;
Thread1 td2 = new Thread1();
td2.tag = false;
Thread zhangsan = new Thread(td1);
Thread lisi = new Thread(td2);
zhangsan.start();
lisi.start();
}
}
2.wait和sleep的区别
class Thread2 implements Runnable{
int i = 10;// 成员变量
synchronized public void run() {
for(; i>= 0; i--) {
if(i == 5 && Thread.currentThread().getName().equals("t1")) {
try {
// Thread.sleep(1000);// 等待 1000毫秒
// wait(1000);// 等待 1000毫秒
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if(i == 3) {
notify();// 唤醒 等待池任意一个
System.out.println("我醒了");
//notifyAll();//唤醒等待池所有
}
System.out.println(Thread.currentThread().getName() + ":" + i);
}
}
}
public class TestWait {
public static void main(String[] args) {
Thread2 td1 = new Thread2();
Thread t1 = new Thread(td1,"t1");
Thread t2 = new Thread(td1,"t2");
t1.start();
t2.start();
}
}
3.BlockingQeue
生产消费者模式
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
/**生产者*/
class Producer implements Runnable{
//篮子
private BlockingQueue<Integer> q;
public Producer(BlockingQueue<Integer> q) {
this.q = q;
}
@Override
public void run() {
//生产
for(int i = 1; i <= 10 ; i++) {
try {
Thread.sleep(2000);// 2秒
q.put(i);//添加元素 :阻塞
// q.add(i);// 非阻塞,加到第3个后会抛出异常
System.out.println(Thread.currentThread().getName()+"生产了:" + i);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
/**消费者*/
class Consumer implements Runnable{
private BlockingQueue<Integer> q ;
public Consumer(BlockingQueue<Integer> q) {
super();
this.q = q;
}
public void run() {
try {
Thread.sleep(10000);//等10秒
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
for(int i = 1; i <= 10 ; i ++) {
try {
Thread.sleep(2000);
// 阻塞方法
q.take();
// q.remove();//非阻塞,拿到第3个后会抛出异常
System.out.println(Thread.currentThread().getName()+"消费了:" + i);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
public class TestProducer {
public static void main(String[] args) {
//队列
ArrayBlockingQueue<Integer> q = new ArrayBlockingQueue<>(3);
Producer p = new Producer(q);
Thread tp = new Thread(p,"生产者");
Consumer c = new Consumer(q);
Thread tc = new Thread(c,"消费者");
tp.start();
tc.start();
}
}
4.守护线程
简单的老说,就是子线程与主线程同生共死
class SubThread implements Runnable{
public void run() {
Scanner input = new Scanner(System.in);
System.out.println("-- 输入一个数字:");
int num = input.nextInt();
System.out.println("数字是:" + num);
}
}
public class TestThread {
public static void main(String[] args) {
SubThread sub = new SubThread();
Thread t1 = new Thread(sub,"t1");
t1.setDaemon(true);// 设置守护线程
t1.start();
System.out.println("主线程结束");
}
}
5.网络
6.协议
7.IP地址
获取本机IP:
System.out.println(InetAddress.getLocalHost());
8.InetAddress
实例如下:
//IP封装
// InetAddress: DESKTOP-JBSD6AK/192.168.31.61
System.out.println(InetAddress.getLocalHost());
// 根据 主机名 或 IP地址 获得一个 IP封装 InetAddress
InetAddress net = InetAddress.getByName("DESKTOP-JBSD6AK");
System.out.println(net);
System.out.println(net.getHostName());// DESKTOP-JBSD6AK
System.out.println(net.getHostAddress());//192.168.31.61
9.域名
DNS:域名解析器
10.端口
11.URL的6个查询
统一资源定位符。
URL url = new URL("http://127.0.0.1:7890/data/a.docx?id=1&page=5#hello");
System.out.println(url.getProtocol());// http,获得协议
System.out.println(url.getPort());// 7890,获得端口号
System.out.println(url.getDefaultPort());// 80,获得协议的默认的端口
System.out.println(url.getQuery());// id=1&page=5,获得查询字符串
System.out.println(url.getRef());// hello,获得某个片段
12.数据传输
TCP: 安全的。
C/S: 客户端/服务器。
Socket :客户端
ServerSocket:服务器。
B/S:浏览器 /服务器。
UDP:非安全的。速度快。
1.实例:客户端与服务器之间传输字符串
客户端:client
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;
/**客户端*/
public class Clinet {
public static void main(String[] args) throws UnknownHostException, IOException {
// 客户端 127.0.0.1服务器的IP,服务器的端口
Socket socket = new Socket(InetAddress.getLocalHost(),7890 );
//-------------------流-----------------------------
//获得底层流
InputStream is = socket.getInputStream();
OutputStream os = socket.getOutputStream();
//包装
Scanner in = new Scanner(is);
PrintWriter out = new PrintWriter(os,true);//** true
//---------------------------------------------------
// 读服务器的信息;
String sr,sw;
sr = in.nextLine();//读一行
System.out.println("服务器说了:" + sr);
// 回: 发信息给服务器
out.println("我是客户端,我收到了");
//关流
socket.close();
}
}
服务器:Server
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
/**服务器*/
public class Server {
public static void main(String[] args) throws IOException {
// 建立一个服务器
ServerSocket server = new ServerSocket(7890);
// 获得一个Socket 阻塞
Socket socket = server.accept();
//-------------------流---------------------------
//获得底层的双向流
InputStream is = socket.getInputStream();//输入
OutputStream os = socket.getOutputStream();//输出
//包装
Scanner in = new Scanner(is);//
PrintWriter out = new PrintWriter(os,true);// *** true
//-----------------------------------------------------------
String sr ,sw;
//给客户端 发送一条信息:
out.println("服务器说你好");
// 读: 读 客户端发过来的信息
sr = in.nextLine();
System.out.println("客户端说了:" + sr);
//关流
socket.close();
}
}
输出如下:
2.实例:客户端与服务器之间实时聊天
客户端:client
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;
/**客户端*/
public class Client {
public static void main(String[] args) throws UnknownHostException, IOException {
// 客户端 127.0.0.1服务器的IP,服务器的端口
Socket socket = new Socket(InetAddress.getLocalHost(),7890 );
//-------------------流-----------------------------
//获得底层流
InputStream is = socket.getInputStream();
OutputStream os = socket.getOutputStream();
//包装
Scanner in = new Scanner(is);
PrintWriter out = new PrintWriter(os,true);//** true
//---------------------------------------------------
String sr,sw;
Scanner input = new Scanner(System.in);
while(true) {
sr = in.nextLine();
System.out.println("服务器说:" + sr);
//回信息给服务器
System.out.print("--客户端:");
sw = input.next();//控制台输入
out.println(sw);// 写回服务器
if(sw.equals("end")) {
break;
}
}
//关流
socket.close();
}
}
服务器:Server
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
/**服务器*/
public class Server {
public static void main(String[] args) throws IOException {
// 建立一个服务器
ServerSocket server = new ServerSocket(7890);
// 获得一个Socket 阻塞
Socket socket = server.accept();
//-------------------流---------------------------
//获得底层的双向流
InputStream is = socket.getInputStream();//输入
OutputStream os = socket.getOutputStream();//输出
//包装
Scanner in = new Scanner(is);//
PrintWriter out = new PrintWriter(os,true);// *** true
//-----------------------------------------------------------
System.out.println("---------服务器-------------");
//先发一个信息给客户端
out.println("客户端连接服务器成功");
//
String sr,sw;
Scanner input = new Scanner(System.in);
while(true) {
sr = in.nextLine();
System.out.println("客户端说:" + sr);
System.out.print("--服务器:");
sw = input.next();//控制台输入
out.println(sw);
if(sw.equals("end")) {
break;
}
}
//关流
socket.close();
}
}
输出如下:
13.编写:同步 卖票
法一:
class Station implements Runnable{
private int count = 20;
synchronized public void Ticket() {
count -= 1;
System.out.println(
Thread.currentThread().getName()
+"卖了一张票,余票为"
+count);
}
@Override
public void run() {
for (int i = 1; i <= 10; i++) {
this.Ticket();;
}
}
}
public class day0719 {
public static void main(String[] args) {
Station ticket = new Station();
Thread t1 = new Thread(ticket,"1");
Thread t2 = new Thread(ticket,"2");
t1.start();
t2.start();
}
}
法二:
class Station extends Thread{
private int count = 20;
synchronized public void Ticket() {
count -= 1;
System.out.println(
Thread.currentThread().getName()
+"卖了一张票,余票为"
+count);
}
@Override
public void run() {
for (int i = 1; i <= 10; i++) {
this.Ticket();;
}
}
}