java多线程初步

Java多线程:

进程:一个进程对应一个程序,例如:在Windows中启动Word,开发环境下启动JVM

单核计算机同一个时间节点只能执行一个进程,双核对应一个时间点两个进程。

进程之间相互独立。

多进程,一边游戏,一边音乐(本质上是进程来回切换)

多进程不是提高执行速度,而是提高CPU使用率。

线程:线程是一个进程中的执行场景(客户端访问服务器)>一个进程对应多个线程

线程本质上也是来回切换的、间断的,只是计算机处理速度非常高。

多线程的作用:不是提高速度,而是提高应用程序使用率

线程之间共享“堆内存和方法区内存”栈内存是独立的“一个线程一个栈”

 

Java程序运行原理:

执行Java命令的时候,启动JVM ,开启进程,该进程会自动开启一个‘主线程’,这个‘主线程’会去某个类中调用main方法(所以main方法运行在‘主线程’中)。

 

Java中实现线程的方式

  1. 写一个类继承Thread类
  2. 写一个类实现runnable接口(推荐使用)

Thread中重要的两个方法:

Public void run()  à 该方法是启动线程时自动调用

Public void start() 启动线程

 

 

 

线程生命周期:

线程优先级:

Java采用抢占CPU方式执行,优先级高的并不先执行,只是它获取时间片相对多一点。

最低1 最高10 默认5

通过setPriority()改变优先级

例:

package com.guanghui;

 

/*

 * 1 Thread.sleep(毫秒)

 * 2 sleep是一个静态方法,所以调用的时候类名.sleep()

    * 3 该方法起到阻塞当前线程腾出CPU让给其他线程

 */

public class ThreadSleep {

    public static void main(String[] args) throws InterruptedException {

        Thread t1 = new Processor();

        //给线程取名字

        t1.setName("haha");

        //开启线程

        t1.start();

        for (int i = 0; i < 10; i++) {

            System.out.println(Thread.currentThread().getName()+"-->"+i);

            //这里的异常可以向上抛出,因为没有继承父类run方法

            Thread.sleep(500);

        }

    }

 

}

class Processor extends Thread{

    @Override

    //重写run方法

    //这里不能抛出异常,因为父类run方法中没有抛出异常

    public void run() {

        for (int i = 0; i < 10; i++) {

            System.out.println(Thread.currentThread().getName()+ "---->"+i);

            try {

                Thread.sleep(1000);

            } catch (InterruptedException e) {

                // TODO Auto-generated catch block

                e.printStackTrace();//让当前线程阻塞1s

            }

        }

    }

}

 

 

终止线程随眠:

package com.guanghui;

 

/*

 * 终止线程随眠,

注:可以调用interrupt()方法,该方法使用异常处理,不推荐使用

 */

public class ThreadSleep2 {

 

    public static void main(String[] args) throws InterruptedException {

 

        Processer p = new Processer();

        Thread t = new Thread(p);

 

        t.setName("t");

        t.start();

 

        Thread.sleep(5000);

 

        p.run = false;

    }

 

}

 

class Processer implements Runnable {

 

    boolean run = true;

 

    public void run() {

 

        for (int i = 0; i < 10; i++) {

 

            if (run) {

 

                try {

                    Thread.sleep(1000);

                } catch (InterruptedException e) {

                    e.printStackTrace();

                }

                System.out

                        .println(Thread.currentThread().getName() + "-->" + i);

 

            } else

                return;

        }

 

    }

 

}

线程同步(加锁)

同步编程模型:线程之间有序执行,下一个执行必须等待上一个线程执行完毕(银行取钱、幻读)

异步编程模型:线程之间独立执行,抢占cup执行

 

为什么引入线程同步?

为了数据安全,此时类似单线程。

 

什么情况使用线程同步

  1. 满足多线程环境
  2. 共享同一数据
  3. 共享数据涉及到数据的修改

 

案例:

此案例为线程异步(不安全)

package com.guanghui;

 

public class ThreadTest {

 

         public static void main(String[] args) {

                  

                   Account account = new Account("zhangsan", 5000);

                  

                   Processer p = new Processer(account);

 

                   Thread t1 = new Thread(p);

                   Thread t2 = new Thread(p);

 

                   t1.start();

                   t2.start();

         }

 

}

 

// 取钱线程

class Processer implements Runnable {

 

         Account custmer;

 

         public Processer(Account custmer) {

                   this.custmer = custmer;

         }

 

         public void run() {

                   custmer.getMoney(1000);

                   System.out.println("取款成功,余额:" + custmer.getBalance());

         }

}

 

//Account类

public class Account {

         private String actno;

         private double balance;

        

         public String getActno() {

                   return actno;

         }

 

         public void setActno(String actno) {

                   this.actno = actno;

         }

 

         public double getBalance() {

                   return balance;

         }

 

         public void setBalance(double balance) {

                   this.balance = balance;

         }

 

         public Account() {

         }

 

         public Account(String actno, double balance) {

                   this.actno = actno;

                   this.balance = balance;

         }

        

         public void getMoney(double money) {

                   double after = balance -money;

                  

                   this.setBalance(after);            

         }

}

以下改进(线程同步),执行效率降低,但是数据安全。

public void getMoney(double money) {

                  

                   //把需要同步的代码放入synchronize语句块中,this表示Account类的当前对象,当t1线程进入synchronize时会拿到对象锁直到把语句块执行完才归还,这个过程中其他线程进入synchronize拿不到对象锁不能执行该语句块。Synchronize关键字可以修饰成员方法,也表示当前对象锁

                   synchronized (this) {

                            double after = balance -money;

                            try {

                                     //为了验证,随眠

                                     Thread.sleep(500);

                            } catch (InterruptedException e) {

                                      // TODO Auto-generated catch block

                                     e.printStackTrace();

                            }

                            this.setBalance(after);   

                   }

                           

         }

 

Synchronize类锁案例

package com.guanghui;

/*

 * synchronize可以修饰静态方法表示类锁类

 */

public class ThreadSynchdTest {

 

         public static void main(String[] args) throws InterruptedException {

                  

                   Thread t1 = new Thread(new Demo01());

                   Thread t2 = new Thread(new Demo01());

                  

                   t1.setName("t1");

                   t2.setName("t2");

                  

                   t1.start();

                  

                   //随眠,使t1线程优先执行

                   Thread.sleep(1000);

                  

                   t2.start();

                  

         }

 

}

 

class Demo01 implements Runnable{

        

         public void run() {

                   if("t1".equals(Thread.currentThread().getName())){

                            Demo02.m1();

                            }

                   if("t2".equals(Thread.currentThread().getName())){

                            Demo02.m2();

                   }

                  

         }

}

 

class Demo02

{

         //此处synchronize修饰静态方法拿到类锁

         public synchronized static void m1(){

                   try {

                            Thread.sleep(10000);

                   } catch (InterruptedException e) {

                            e.printStackTrace();

                   }

                   System.out.println("m1 >>>>");

                  

         }

         //由于类锁被m1拿到,所以此处必须等待m1方法执行完毕才能运行

         public  synchronized static void m2() {

                   System.out.println("m2 》》》》");

                  

         }

}

 

死锁

守护线程

线程分为用户线程和守护线程,一般来说守护线程是一个无限循环,它会等待用户线程结束才会跟着结束,例如JVM垃圾回收器就是一个守护线程,只有应用程序中所有线程结束,它才会结束。

定时器Timer

指定某一任务特定时间开始,间隔时间执行。

步骤:

  1. 创建定时器对象
  2. 指定定时任务(schedule方法)

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值