继承Thread类
//创建线程方式一:继承Thread类,重写run()方法,调用start开启线程
public class TestThread1 extends Thread{
@Override
public void run() {
for (int i = 0; i < 20; i++) {
System.out.println("我在看代码"+i);
}
}
public static void main(String[] args) {
//main线程,主线程
//创建一个线程对象
TestThread1 testThread1 = new TestThread1();
//调用start方法开启线程
testThread1.start();
for (int i = 0; i < 20; i++) {
System.out.println("我在学习多线程"+i);
}
}
}
网图下载
工具包:commons-io-2.6.jar
import org.apache.commons.io.FileUtils;
import java.io.File;
import java.io.IOException;
import java.net.URL;
//实现多线程同步下载器
public class TestThread2 extends Thread{
private String url;
private String name;
public TestThread2(String url, String name){
this.name = name;
this.url = url;
}
//线程执行体
@Override
public void run() {
WebDownloader webDownloader = new WebDownloader();
webDownloader.downloader(url,name);
System.out.println("下载了文件名为"+name);
}
public static void main(String[] args) {
TestThread2 testThread2 = new TestThread2("https://img-blog.csdnimg.cn/d401aef9ed0f4c9394ae8930e6686c26.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6Lev6L655pGG5pGK,size_20,color_FFFFFF,t_70,g_se,x_16","1.jpg");
testThread2.start();
}
}
//下载器
class WebDownloader{
//下载方法
public void downloader(String url,String name){
try {
FileUtils.copyURLToFile(new URL(url),new File(name));
} catch (IOException e) {
e.printStackTrace();
System.out.println("IO异常,downloader方法出现问题");
}
}
}
实现runnable接口
//创建线程方式2:实现runnable接口,重写run方法,执行线程需要丢入runnable接口实现类,调用start方法
public class TestThread3 implements Runnable{
@Override
public void run() {
for (int i = 0; i < 20; i++) {
System.out.println("我在看代码" + i);
}
}
public static void main(String[] args) {
//main线程,主线程
//创建runnable接口的实现类对象
TestThread3 testThread3 = new TestThread3();
//创建线程对象,通过线程对象来开启我们的线程,代理
Thread thread = new Thread(testThread3);
thread.start();
for (int i = 0; i < 100; i++) {
System.out.println("我在学习多线程"+i);
}
}
}
则用实现runnable接口的网图下载只需要改两处:
public class TestThread2 implements Runnable{
public static void main(String[] args) {
TestThread2 testThread2 = new TestThread2("https://img-blog.csdnimg.cn/d401aef9ed0f4c9394ae8930e6686c26.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6Lev6L655pGG5pGK,size_20,color_FFFFFF,t_70,g_se,x_16","1.jpg");
new Thread(testThread2).start();
}
小结
初识并发问题
//多个线程同时操作同一个对象
//买火车票的例子
//发现问题:多个线程操作同一个资源的情况下,线程不安全,数据紊乱
public class TestThread4 implements Runnable{
private int ticketNums = 10;
@Override
public void run() {
while (true){
if(ticketNums<=0)
break;
try {
Thread.sleep(200);//模拟延时
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"拿到了第"+ticketNums--+"张票");
}
}
public static void main(String[] args){
TestThread4 ticket = new TestThread4();
new Thread(ticket,"小明").start();
new Thread(ticket,"小红").start();
new Thread(ticket,"黄牛").start();
}
}
龟兔赛跑
public class Race implements Runnable{
//胜利者
private static String winner;
@Override
public void run() {
for (int i = 0; i <= 200; i++) {
//模拟兔子休息
if(Thread.currentThread().getName().equals("兔子")&& i%10==0){
try {
Thread.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//判断比赛是否结束
boolean flag = gameOver(i);
//如果比赛结束了,就停止程序
if(flag){
break;
}
System.out.println(Thread.currentThread().getName()+"跑了"+i+"步");
}
}
//判断比赛是否完成
private boolean gameOver(int steps){
if(winner!=null) {
return true;
}{
if(steps>=200) {
winner = Thread.currentThread().getName();
System.out.println("winner is" + winner);
return true;
}
}
return false;
}
public static void main(String[] args){
Race race = new Race();
new Thread(race,"兔子").start();
new Thread(race,"乌龟").start();
}
}
Lambda表达式
静态代理模式
//静态代理模式总结:
//真实对象和代理对象都要实现同一个接口
//代理对象要代理真实角色
//好处:代理对象可以做很多真实对象做不了的事情,真实对象专注做自己的事情
public class StaticProxy {
public static void main(String[] args){
/*new Thread(new Runnable() {
@Override
public void run() {
System.out.println("我爱你");
}
}).start();*/
new Thread(()-> System.out.println("我爱你")).start();//Lambda表达式
//此处对比理解,Thread代理runnable对象
/*Weddingcompany weddingcompany = new Weddingcompany(new You());//把你给婚庆公司
weddingcompany.HappyMarry();*/
new Weddingcompany(new You()).HappyMarry();
}
}
interface Marry{
void HappyMarry();
}
//真实角色,你去结婚
class You implements Marry{
@Override
public void HappyMarry() {
System.out.println("老秦要结婚了");
}
}
//代理角色,帮你结婚
class Weddingcompany implements Marry{
//代理谁--》真实目标角色
private Marry target;
public Weddingcompany(Marry target) {
this.target = target;
}
@Override
public void HappyMarry() {
before();
this.target.HappyMarry();//真实对象
after();
}
private void after() {
System.out.println("布置现场");
}
private void before() {
System.out.println("收尾款");
}
}
线程停止
//测试stop
//1.建议线程正常停止-->利用次数,不建议死循环
//2.建议使用标志位--->设置一个标志位
//3.不要使用stop或destroy等过时或JDK不建议使用的方法
public class TestStop implements Runnable {
//设置一个标志位
private boolean flag = true;
@Override
public void run() {
int i = 0;
while (flag){
System.out.println("run...Thread"+i++);
}
}
//设置一个公开的方法停止线程,转换标志位
public void stop(){
this.flag = false;
}
public static void main(String[] args){
TestStop testStop = new TestStop();
new Thread(testStop).start();
for (int i = 0; i < 1000; i++) {
System.out.println("main"+i);
if(i==900){
//调用stop方法切换标志位,让线程停止
testStop.stop();
System.out.println("线程该停止了");
}
}
}
}
线程休眠sleep
import java.text.SimpleDateFormat;
import java.util.Date;
public class TestSleep {
public static void main(String[] args){
//打印当前系统时间
Date startTime = new Date(System.currentTimeMillis());//获取系统当前时间
while (true){
try {
Thread.sleep(1000);
System.out.println(new SimpleDateFormat("HH:mm:ss").format(startTime));
startTime = new Date(System.currentTimeMillis());//更新当前时间
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
线程礼让yield
public class TestYield {
public static void main(String[] args) {
MyYield myYield = new MyYield();
new Thread(myYield,"a").start();
new Thread(myYield,"b").start();
}
}
class MyYield implements Runnable{
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"线程开始执行");
Thread.yield();//礼让
System.out.println(Thread.currentThread().getName()+"线程停止执行");
}
}
##线程强制执行join
public class TestJoin implements Runnable{
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println("线程Vip来了"+i);
}
}
public static void main(String[] args) throws InterruptedException {
Thread thread = new Thread(new TestJoin());
thread.start();
for (int i = 0; i < 1000; i++) {
if(i==200){
thread.join();//插队
}
System.out.println("main"+i);
}
}
}
线程状态观测
public class TestState {
public static void main(String[] args) throws InterruptedException {
Thread thread = new Thread(() -> {
for (int i = 0; i < 5; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("//");
});
//观察状态
Thread.State state = thread.getState();
System.out.println(state);//NEW
//观察启动
thread.start();
state = thread.getState();
System.out.println(state);//RUN
while (state != Thread.State.TERMINATED) {//只要线程不终止,就一直输出状态
Thread.sleep(100);
state = thread.getState();//更新线程状态
System.out.println(state);
}
}
}
线程优先级
public class TestPriorty {
public static void main(String[] args){
//主线程默认优先级
System.out.println(Thread.currentThread().getName()+"-->"+Thread.currentThread().getPriority());
MyPriority myPriority = new MyPriority();
Thread t1 = new Thread(myPriority);
Thread t2 = new Thread(myPriority);
Thread t3 = new Thread(myPriority);
Thread t4 = new Thread(myPriority);
//先设置优先级,再启动
t1.start();
t2.setPriority(1);
t2.start();
t3.setPriority(3);
t3.start();
t4.setPriority(Thread.MAX_PRIORITY);
t4.start();
}
}
class MyPriority implements Runnable{
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"-->"+Thread.currentThread().getPriority());
}
}
守护daemon线程
public class TestDaemon {
public static void main(String[] args){
God god = new God();
You you = new You();
Thread thread = new Thread(god);
thread.setDaemon(true);//默认是false表示是用户线程,正常的线程都是用户线程
thread.start();
new Thread(you).start();
}
}
class God implements Runnable{
@Override
public void run() {
while (true){
System.out.println("上帝保佑着你");
}
}
}
class You implements Runnable{
@Override
public void run() {
for (int i = 0; i < 36500; i++) {
System.out.println("你一生都开心地活着");
}
System.out.println("-===goodbye! world===-");
}
}
线程同步
锁机制:synchronized
public class UnsafeBank {
public static void main(String[] args) {
//账户
Account account = new Account(1000,"结婚基金");
Drawing you = new Drawing(account,50,"你");
Drawing wife = new Drawing(account,100,"wife");
you.start();
wife.start();
}
}
//账户
class Account{
int money;
String name;
public Account(int money, String name) {
this.money = money;
this.name = name;
}
}
//模拟取款
class Drawing extends Thread{
Account account;
int drawingMoney;
int nowmoney;
public Drawing(Account account, int drawingMoney, String name) {
super(name);
this.account = account;
this.drawingMoney = drawingMoney;
}
//取钱
//synchronize默认锁的是this
@Override
public void run() {
//锁的对象是变化的量,需要增删改查的对象
synchronized (account){
//判断有没有钱
if(account.money-drawingMoney<0){
System.out.println(Thread.currentThread().getName()+"钱不够了");
return;
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//卡内余额 = 余额-取的钱
account.money = account.money - drawingMoney;
nowmoney = nowmoney + drawingMoney;
System.out.println(account.name+"余额为:"+account.money);
System.out.println(this.getName()+"手里的钱:"+nowmoney);
}
}
}
死锁
public class DeadLock {
public static void main(String[] args) {
Makeup g1 = new Makeup(0,"灰姑娘");
Makeup g2 = new Makeup(1,"白雪公主");
g1.start();
g2.start();
}
}
//口红
class Lipstick{
}
//镜子
class Mirror{
}
class Makeup extends Thread{
//需要的资源只有一份,用static来保证只有一份
static Lipstick lipstick = new Lipstick();
static Mirror mirror = new Mirror();
int choice;
String girlName;
public Makeup(int choice, String girlName) {
this.choice = choice;
this.girlName = girlName;
}
@Override
public void run() {
try {
makeup();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//化妆,互相持有对方的锁,就是需要拿到对方的资源
private void makeup() throws InterruptedException {
if(choice==0){
synchronized (lipstick){
//获得口红的锁
System.out.println(this.girlName+"获得口红的锁");
Thread.sleep(1000);
}
synchronized (mirror){//一秒钟后想获得镜子的锁
System.out.println(this.girlName+"获得镜子的锁");
}
}else {
synchronized (mirror){
//获得镜子的锁
System.out.println(this.girlName+"获得镜子的锁");
Thread.sleep(2000);
}
synchronized (lipstick){//一秒钟后想获得口红的锁
System.out.println(this.girlName+"获得口红的锁");
}
}
}
}
lock锁
import java.util.concurrent.locks.ReentrantLock;
public class TestLock {
public static void main(String[] args){
TestLock2 testLock2 = new TestLock2();
new Thread(testLock2).start();
new Thread(testLock2).start();
new Thread(testLock2).start();
}
}
class TestLock2 implements Runnable{
int ticketNums = 10;
//定义lock锁
private final ReentrantLock lock = new ReentrantLock();
@Override
public void run() {
while (true){
try {
lock.lock();//加锁
if(ticketNums>0){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(ticketNums--);
}else {
break;
}
} finally {
lock.unlock();
}
}
}
}
线程通信
管程法
public class TestPc {
public static void main(String[] args){
SynContainer container = new SynContainer();
new Producer(container).start();
new Consumer(container).start();
}
}
//生产者
class Producer extends Thread{
SynContainer container;
public Producer(SynContainer container) {
this.container = container;
}
@Override
public void run() {
for (int i = 0; i < 100; i++) {
container.push(new Chicken(i));
System.out.println("生产了"+i+"只鸡");
}
}
}
//消费者
class Consumer extends Thread{
SynContainer container;
public Consumer(SynContainer container) {
this.container = container;
}
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println("消费了-->"+container.pop().id+"只鸡");
}
}
}
//产品
class Chicken{
int id;
public Chicken(int id) {
this.id = id;
}
}
//缓冲区
class SynContainer{
//需要一个容器大小
Chicken[] chickens = new Chicken[10];
//容器计数器
int count = 0;
//生产者放入产品
public synchronized void push(Chicken chicken){
//如果容器满了,就需要等待消费者消费
if(count== chickens.length){
//通知消费者消费,生产者等待
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//如果没有满,就放入产品
chickens[count] = chicken;
count++;
//可以通知消费者消费了
this.notifyAll();
}
//消费者消费产品
public synchronized Chicken pop(){
//判断能否消费
if(count==0){
//等待生产者生产,消费者等待
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//如果可以消费
count--;
Chicken chicken = chickens[count];
//吃完了,通知生产者生产
this.notifyAll();
return chicken;
}
}
信号灯法
使用线程池
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class TestPool {
public static void main(String[] args){
//创建服务,创建线程池
//newFixedThreadPool参数为:线程池大小
ExecutorService service = Executors.newFixedThreadPool(10);
service.execute(new MyThread());
service.execute(new MyThread());
service.execute(new MyThread());
service.execute(new MyThread());
//关闭连接
service.shutdown();
}
}
class MyThread implements Runnable{
@Override
public void run() {
System.out.println(Thread.currentThread().getName());
}
}
网络编程
IP
ip地址:InetAddress
127.0.0.1 本机localhost
import java.net.InetAddress;
import java.net.UnknownHostException;
public class TestInetAddress {
public static void main(String[] args){
try {
//查询本机地址
InetAddress inetAddress1 = InetAddress.getByName("127.0.0.1");
System.out.println(inetAddress1);
InetAddress inetAddress3 = InetAddress.getByName("localhost");
System.out.println(inetAddress3);
InetAddress inetAddress4 = InetAddress.getLocalHost();
System.out.println(inetAddress4);
//查询网络ip地址
InetAddress inetAddress2 = InetAddress.getByName("www.baidu.com");
System.out.println(inetAddress2);
//常用方法
//System.out.println(inetAddress2.getAddress());
System.out.println(inetAddress2.getCanonicalHostName());//获取规范名字
System.out.println(inetAddress2.getHostAddress());//ip
System.out.println(inetAddress2.getHostName());//域名,或自己电脑的名字
} catch (UnknownHostException e) {
e.printStackTrace();
}
}
}
端口
InetSocketAddress
共有端口号0~1023
http:80
https:443
ftp:21
Telent:23
程序注册端口:1024~49151,分配用户或者程序
Tomcat:8080
MySQL:3306
Oracle:1521
动态、私有:49152~65535
netstat -ano//查看端口
tcp传输文件
import java.io.*;
import java.net.InetAddress;
import java.net.Socket;
public class TcpClientDemo01 {
public static void main(String[] args) throws Exception {
//创建一个Socket连接
Socket socket = new Socket(InetAddress.getByName("127.0.0.1"),9000);
//创建一个输出流
OutputStream os = socket.getOutputStream();
//读取文件
FileInputStream fis = new FileInputStream(new File("cat.jpg"));
//写出文件
byte[] buffer = new byte[1024];
int len;
while ((len=fis.read(buffer))!=-1){
os.write(buffer,0,len);
}
//通知服务器,结束了
socket.shutdownOutput();
//确定服务器接收完毕,才能够断开连接
InputStream inputStream = socket.getInputStream();
//String byte[]
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer2 = new byte[1024];
int len2;
while ((len2=inputStream.read(buffer2))!=-1){
baos.write(buffer2,0,len2);
}
System.out.println(baos.toString());
//关闭资源
baos.close();
inputStream.close();
fis.close();
os.close();
socket.close();
}
}
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
public class TcpServerDemo01 {
public static void main(String[] args) throws Exception {
//创建服务
ServerSocket serverSocket = new ServerSocket(9000);
//监听客户端连接
Socket socket = serverSocket.accept();//阻塞式监听,会一直等待客户端连接
//获取输入流
InputStream is = socket.getInputStream();
//文件输出
FileOutputStream fos = new FileOutputStream(new File("receive.jpg"));
byte[] buffer = new byte[1024];
int len;
while((len=is.read(buffer))!=-1){
fos.write(buffer,0,len);
}
//通知客户端接收完毕
OutputStream os = socket.getOutputStream();
os.write("我接受完毕了,你可以断开了".getBytes(StandardCharsets.UTF_8));
//关闭资源
fos.close();
socket.close();
is.close();
serverSocket.close();
}
}