线程复习

Thread 类

线程的状态

==sleep()wait()==方法都是Java中造成线程阻塞的方法
在这里插入图片描述

参考大神的解释
而使用sleep()和wait()两种方法对于“CPU执行权”和“同步锁”的方式不同:
①sleep()释放CPU执行权,但不释放同步锁;
②wait()释放CPU执行权,也释放同步锁,使得其他线程可以使用同步控制块或者方法。

Thread(String m)//创建一个以m命名的线程
	Thread(ThreadGroup g,String m)//创建以m命名,属于指定的线程组g
	getPriority()//获得线程的优先级
	setPriority()//设定线程的优先级
	currentThread()//获得正在占用CPU的那个线程
	getName()//获得 线程名字
	isAlive()//返回boolean,查询线程是否还活跃
	destroy()//强制线程生命周期结束
	stop()//强制线程生命周期结束,并完成一些清理工作,及抛出异常
	suspend()//挂起线程,处于不可
	resume()//恢复挂起的线程,重新进入就绪队列排队
	yield()//线程礼让
Runnable接口
	只有一个run() 需要实现
线程互斥
	synchronized 定义边界段
线程同步
	wait() //让线程一直等待
	notify()notifyAll() 方法唤醒

abstract与implements的关系

写出抽象类-->就是为了继承-->然后实现

1、在类的声明中,通过关键字extends来创建一个类的子类。
一个类通过关键字implements声明自己使用一个或者多个接口。
extends 是继承某个类, 继承之后可以使用父类的方法, 也可以重写父类的方法;
implements 是实现多个接口, 接口的方法一般为空的, 必须重写才能使用
2、extends是继承父类,只要那个类不是声明为final或者那个类定义为abstract的就能继承
JAVA中不支持多重继承,但是可以用接口 来实现,这样就要用到implements,继承只能继承一个类,
但implements可以实现多个接口,用逗号分开就行了 比如 :
class A extends B implements C,D,E

接口实现的注意点:

a.实现一个接口就是要实现该接口的所有的方法(抽象类除外)。 
b.接口中的方法都是抽象的。  
c.多个无关的类可以实现同一个接口,一个类可以实现多个无关的接口。

网络编程

常用的端口信息

1、通信概述
TCP   打电话
UDP   发短信
2、端口
端口表示一个程序的进程
规定进程0~65535
TCP,UDP  65535*2 tcp:80 ;udp:80 同个协议下,端口号不能冲突
端口分类
公有端口0~1023   HTTP:80    HTTPS:443  FTP:21   Telent:23 
程序注册端口1024~49151,分配用户或程序
Tomact 8080 ;MySQL 3306 ;Oracl 1521
动态、私有 49152~65535 
netstat -ano #查看所有端口
netstat -ano|findstr "3306"  #查看指定端口
tasklist|findstr "8696"  查看端口的进程

根据主机名、IP获取客户信息

public class TestAddress {
    public static void main(String[] args) {
        try {//查看本机地址
            System.out.println(InetAddress.getByName("127.0.0.1"));
            System.out.println(InetAddress.getByName("localhost"));
            System.out.println(InetAddress.getLocalHost());
            //查询网站地址
            InetAddress byName = InetAddress.getByName("www.baidu.com");
            System.out.println(byName);
            //常用方法
            System.out.println(byName.getAddress());
            System.out.println(byName.getCanonicalHostName());   //规范名称
            System.out.println(byName.getHostAddress());   //ip
            System.out.println(byName.getHostName());  //域名,或本机名称

        } catch (UnknownHostException e) {
            e.printStackTrace();
        }
    }
}

理解TCP、UDP

通讯协议

网络通信协议:速率,传输码率,代码结构,传输控制
TCP 用户数据协议 UDP用户数据报协议 TCP/IP网络互联协议

TCP 三次握手

A你瞅啥 B瞅你咋滴 A来干一架

TCP 四次挥手

A我走了 B你要走吗 B你真的要走吗 A我走了

线程

wait() 与 await()

1. wait()是Object超类中的方法,而await()是ConditionObject类里面的方法.

2. await会导致当前线程被阻塞,会释放锁,这点和wait是一样的

3. await中的lock不再使用synchronized把代码同步包装起来

4. await的阻塞需要另外的一个对象condition

5. notify是用来唤醒使用wait的线程;而signal是用来唤醒await线程。

6. 所在的超类不同使用场景也不同,wait一般用于Synchronized中,而await只能用于ReentrantLock锁中
## 死锁问题
>  new Thread(T::produce,"线程A").start();
new Thread(()-> T.b(),"线程B").start();
public class One {
    //状态锁
    private Object lock=0;
    //条件变量
    private int now=0,need;
    public void produce(){
        //同步
        synchronized (lock){
            //当前有的不满足需要,进行等待,直到满足条件
            {
                try {
                    //等待阻塞
                    System.out.println(now);
                    now++;
                    System.out.println(now);
                    lock.wait();
                    now++;
                    System.out.println(now);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                System.out.println("我被唤醒了!");
            }
            System.out.println("mmm!");
            // 做其他的事情
        }
    }
    void b(){
        synchronized (lock) {
            System.out.println(now);
            lock.notify();
            System.out.println(Thread.currentThread().getName());
        }
    }

    public static void main(String[] args) {
        One T = new One();
        new Thread(T::produce,"线程A").start();
        new Thread(()-> T.b(),"线程B").start();
    }
}

线程jion

基数一点要大,不然看不出效果
其中jion还可以其他参数

public class MM extends Thread
{
	// 提供一个有参数的构造器,用于设置该线程的名字
	public MM(String name)
	{
		super(name);
	}
	// 重写run()方法,定义线程执行体
	public void run()
	{
		for (int i = 0; i < 100 ; i++ )
		{
			System.out.println(getName() + "  " + i);
		}
	}
	public static void main(String[] args)throws Exception
	{
		// 启动子线程
		new MM("新线程").start();
		for (int i = 0; i < 100 ; i++ )
		{
			if (i == 20)
			{
				MM jt = new MM("被Join的线程");
				jt.start();
				// main线程调用了jt线程的join()方法,main线程
				// 必须等jt执行结束才会向下执行
				jt.join();
			}
			System.out.println(Thread.currentThread().getName() + "  " + i);
		}
	}
}

设置优先级

Thread.yield 线程礼让
Thread.setPriority(Thread.MAX_PRIORITY) 设置优先级

public class YieldTest extends Thread
{
	public YieldTest(String name)
	{
		super(name);
	}
	// 定义run方法作为线程执行体
	public void run()
	{
		for (int i = 0; i < 50 ; i++ )
		{
			System.out.println(getName() + "  " + i);
			// 当i等于20时,使用yield方法让当前线程让步
			if (i == 20)
			{
				Thread.yield();
			}
		}
	}
	public static void main(String[] args)throws Exception
	{
		// 启动两条并发线程
		YieldTest yt1 = new YieldTest("高级");
		// 将ty1线程设置成最高优先级
		yt1.setPriority(Thread.MAX_PRIORITY);
		yt1.start();
		YieldTest yt2 = new YieldTest("低级");
		// 将yt2线程设置成最低优先级
		yt2.setPriority(Thread.MIN_PRIORITY);
		yt2.start();
	}
}

设置后台运行

setDaemon(true);

public class MM extends Thread
{
	// 定义后台线程的线程执行体与普通线程没有任何区别
	public void run()
	{
		for (int i = 0; i < 100 ; i++ )
		{
			System.out.println(getName() + "  " + i);
		}
		System.out.println("总要打印点东西出来噻");
	}
	public static void main(String[] args)
	{
		MM t = new MM();
		// 将此线程设置成后台线程
		t.setDaemon(true);
		// 启动后台线程
		t.start();
		for (int i = 0 ; i < 10 ; i++ )
		{
			System.out.println(Thread.currentThread().getName()
				+ "  " + i);
		}
		// -----程序执行到此处,前台线程(main线程)结束------
		// 后台线程也应该随之结束
		System.out.println("屁就不放一个");
	}
}

多个线程占用问题

Runnable有些问题,会打印出-1票
利用sleep 放大问题
多个线程占用同一个通道 容易出现问题

public class ThreadTwo implements Runnable{
    private int num=10;
    @Override
    public void run() {
        while (true){
            if(num<=0) {
                break;
            }
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()+"拿到第几个线程: "+num--+"票");
        }
    }

    public static void main(String[] args) {
        ThreadTwo a=new ThreadTwo();
        new Thread(a,"小明").start();
        new Thread(a,"老师").start();
        new Thread(a,"黄牛党").start();
    }
}

多线程下载图片

注意:文中用了线程池的方法
注意:文件中需要添加commons io文件

import java.net.URL;
import org.apache.commons.io.FileUtils;
public class Appliction extends Thread{
    @Override
    public void run() {
        EebDownload d=new EebDownload();
        d.downloader(url,name);
        System.out.println("下载文件:"+name);
    }
    private String url;
    private String name;
    private Appliction(String url,String name){
        this.url=url;
        this.name=name;
    }

    public static void main(String[] args) {
        Appliction a=new Appliction("https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fa4.att.hudong.com%2F27%2F67%2F01300000921826141299672233506.jpg&refer=http%3A%2F%2Fa4.att.hudong.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1615693079&t=7f8a9a62fffdda8989a0575e3ef64238","./one/1.jpg");
        Appliction b=new Appliction("https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fa0.att.hudong.com%2F30%2F29%2F01300000201438121627296084016.jpg&refer=http%3A%2F%2Fa0.att.hudong.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1615693079&t=7f1d202d60c2f8962cd0ea73ebd964cf","./one/2.jpg");
        Appliction c=new Appliction("https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fa2.att.hudong.com%2F86%2F10%2F01300000184180121920108394217.jpg&refer=http%3A%2F%2Fa2.att.hudong.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1615693079&t=e8cebd1206f93a4d2c77df894fb7c025","./one/3.jpg");
        a.start();
        b.start();
        c.start();
    }
}

class EebDownload{
    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 异常:");
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值