您的位置:首页 > 编程语言 > Java开发

Java学习第五天笔记总结

2019-03-27 17:43 141 查看

多线程

进程与线程

    打个QQ,开了一个进程,再开个QQ,有开了一个进程,开了迅雷,又开了一个进程。

    在QQ里头可以 传输 文字,语言,小广告,那么可以理解为传输文字,语言,小广告就是开了一个线程,线程可以理解为 “任务”。

    一个进程可以管理多个线程,进程是爹妈,管理众多线程儿子。

    进行本身不执行,只为线程的执行提供运行的环境,申请内容空间的。

什么是多线程

    一个进程里面同时执行多个任务(线程、执行路径)。  

    一个进程里头只是包含一个线程。

    开启多线程,是为了 “同时”执行多个任务,

    也就是 “同时”执行多部分代码。

多线程弊端

    弊端:线程切换耗费额外的资源,切换本身也是耗时间的。

    好处:解决了多部分代码 同时 运行的问题

    案例:验证JVM的启动

[code]
class User extends Object{

protected void finalize() throws Throwable {
System.out.println("我要被回收了");
}
}
public class Demo01 {
public static void main(String[] args) throws InterruptedException {
System.out.println("hello Thread--------");
for(int i = 0;i < 10;i++){
new User();
}
System.gc();//手动触发垃圾回收
Thread.sleep(1);
System.out.println("hello Thread========");
}
}

    通过多次运行,发现输出结果的顺序有随机性,有多个“人”在跑

总结:

(1)JVM启动至少2个线程,一个主(main)线程,垃圾回收线程。

(2)线程之间的执行顺序是随机的,也就是那个线程占有CPU谁就执行。

怎么创建线程

方式一:继承Thread

    代码如下

[code]class MyThread extends Thread{
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"老王,被打死了");
//Thread.currentThread().getName()获取当前线程的名称
}
}
public class Demo02 {
public static void main(String[] args) throws InterruptedException {
MyThread myThread = new MyThread();
myThread.start();//启动一个线程
Thread.sleep(3);//线程休眠
System.out.println(Thread.currentThread().getName()+"老王复活了");
}
}

实现步骤

(1)创建一个类,继承Thread,

(2)子类重写run方法,原因:创建线程目的是为了跑任务,任务代码写在run方法里头

(3)创建子类对象,

(4)开启线程。调用start方法

Thread常用方法和属性

    currentThread:获取当前线程

    name:线程的名称

方式二:Runnable接口

    代码实现

[code]
class MyRunnable implements Runnable{

@Override
public void run() {
for (int i = 0; i <10 ; i++) {
try {
Thread.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"转世"+i);
}
}
}
public class Demo03 {
public static void main(String[] args) {
MyRunnable myRunnable1 = new MyRunnable();
MyRunnable myRunnable2 = new MyRunnable();
Thread thread1 = new Thread(myRunnable1, "小李");
Thread thread2 = new Thread(myRunnable2, "老王");
thread1.start();
thread2.start();
System.out.println(Thread.currentThread().getName()+"完了");
}
}

实现步骤

(1)创建一个类,时间runnable接口

(2)重写run方法,并且在run方法里面,写清楚你要干的活的。

(3)创建一个线程Thread(myRunnable,”线程的名字”)

(4)开启线程

总结     

    java是单继承,如果使用方式一创建线程,要求该类不能继承与其他父类,

    往往我们使用 接口 方式扩展。

    将线程任务 与 线程进行分离,对任务进行单独的封装。

    一般情况下使用第二种方式

线程的调度

    挂号之后病人处于新建状态,

    排队候诊就是就绪状态;

    当轮到医生给你看病的时候,就是运行状态,

    当医生给你开验血单,在等待化验结果的时候,医生给其他病人看病,

    在此之间处于阻塞状态,

    当你拿到化验单医生再次为你服务,恢复为就绪状态。

线程状态:

   新建状态

   就绪状态

   运行状态

   阻塞状态

线程优先级

   可以给线程设置优先级,优先级高的先跑,但是不意味着先跑完。

[code]
class Tach implements Runnable{

private String name;
public Tach(String name){
this.name = name;
}
@Override
public void run() {
for (int i = 0 ; i< 10;i++){
System.out.println("to"+name+i);
Thread.yield();//让步,只会让优先级比自己高得线程

}
System.out.println("bye....");
}
}
public class Demo04 {
public static void main(String[] args) {
Tach zx = new Tach("测试员");
Tach ls = new Tach("项目经理");
Thread t1 = new Thread(zx);
Thread t2 = new Thread(ls);
t1.setPriority(Thread.MAX_PRIORITY);//设置优先级
t2.setPriority(Thread.MIN_PRIORITY);
t1.start();
t2.start();
}
}

线程休眠sleep

    设置休眠的时间,时间到了接着运行。阻塞线程。

    Thread.sleep( 100 );

线程让步yield

    yield()方法可以让当前正在执行的线程暂停,但它不会阻塞该线程,它只是将该线程从运行状态转入就绪状态。

    只会给比自己 >=自己优先级的线程。

线程插队join

[code]
public class Demo05 {
public static void main(String[] args) throws InterruptedException {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName());
}
});
thread.start();
for(int i = 0;i < 5 ;i++){
System.out.println(Thread.currentThread().getName());
if(i==3){
thread.join();
}
}
}
}

线程安全(线程同步)

    一个任务的代码实现超过2行,就有可能出现线程安全问题。

    通过同步代码块的方式,保证 任务 的代码 只能一个线程跑,

    当一个线程在运行同步代码块的时候,其他线程只能等待。

Synchronized:

    保证一个方法或者一个代码块在同一时间只被一个线程访问

线程的死锁

    2个人吃饭,只有2个筷子,每个个右手边各一只,

    吃饭:A拿起右手边,等待B把左手边那个筷子放下,

           B 等待A

    原因:资源的竞争,

线程的协作

    生产者和消费者

    PV操作

    wait:是当前线程进入阻塞状态,相当于P 操作  +

    notify:唤醒此同步锁上阻塞的第一个线程,相当于V操作 -

    notifyALL: 唤醒此同步锁上阻塞的所有线程

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: