多线程1

进程:
正在运行的程序,是系统进行资源分配和调用的独立单位。每一个进程都有自己的内存空间和系统资源。windows是多进程

线程:
在同一个进程内又可以执行多个任务,每一个任务可以看成一个线程,是程序的执行单元,执行路径,是程序使用CPU的最基本单位,线程依赖于进程而存在。 jvm是多线程,至少启动了垃圾回收线程和主线程

线程的特点:
具有随机性。因为cpu的执行是具有随机性的。

进程与线程的区别:
1、进程是包含线程的。每一个进程都是有独立的内存区域,进程间切换开销大
2、线程是进程的一个分支,进程中的多个线程是共享内存区域。cpu在多线程之间切换更快一些

线程有什么用?
当我们的应用程序需要同时做多件事情的时候,需要使用多线程

多进程: 在一个时间段里执行多个任务(程序) ,可以提高CPU使用率。 单CPU在某个时间点只能做一件事,但通过CPU高效切换感觉是同时做多件事情

多线程: 在同一应用程序中多条执行路径同时执行。可以用来执行一些耗时操作。

多线程意义:不是提高程序的执行速度,是为了提高程序的使用率。

程序的执行其实都是在抢CPU的资源,CPU的执行权。多个进程抢该资源,如果其中某一个进程如果执行路径比较多,就有更高的几率抢到CPU的执行权。但不能保证哪个线程在哪个时刻抢到,所有线程具有随机性。

并行:逻辑上同时发生,指在某一个时间内同时运行多个程序
并发:物理上同时发生,指在某一个时间点同时运行多个程序

Thread类
描述线程的类
常用方法:
Thread的常用的方法:
1:如何获取本线程的实例。Thread.currentThread()

2:获得线程的名称。getName()
main线程的名称;main
其他线程:Thread-编号。编号从0开始。

3:设置线程的名称
1;setName()
2:通过构造方法设置名字

4:如何获取本线程的优先级。getPriority()
默认的优先为5.
优先级是1-10
优先级高的线程获得cpu的机会更大一些,但是并不能保证一定能最先拿到cpu的执行权。

5:线程睡眠:sleep(毫秒)
sleep(毫秒,纳秒)

6:join():线程合并。当一个线程需要另外一个线程的结果才能够往下执行,这个时候用join.

7:static void yield():线程礼让。效果不明显。暂停当前执行的线程。

8:如何停止一个线程:让一个线程死亡。
8.1:让线程正常的死亡。当run方法执行完了。
8.2:可以设置线程为后台线程。
setDaemon():true表示后台线程或者守护线程。
当一个应用程序的线程都为后台线程的时候,线程会终止(不保证立刻终止),整个应用程序会终止。
8.3:设置变量的方式。
8.4:中断线程。interrupt()

线程的生命周期

  1. 新建:创建线程对象
  2. 就绪:有执行资格,没抢到CPU,没有执行权
  3. 运行:有执行资格,抢到CPU,有执行权
  4. 阻塞:由于一些操作(sleep(),wait())让线程处于了该状态。没有执行资格,没有执行权,而另一些操作(sleep()时间到,notify())可以把它激活,激活后处于就绪状态。
  5. 死亡:线程对象变成垃圾,等待被回收

    new :创建线程但是没有启动。
    Runnable:正在运行的状态。
    Timed-waiting:处于sleep的状态。
    block:受阻塞。已经具有抢cpu的资格,但是没有抢到cpu.
    terminated:已经死亡的状态。

    * 创建线程的2种方式*
    继承的方式:继承Thread类,重写run()方法(封装被线程调用的方法)。创建对象调用start()方法(先启动线程,然后由jvm去调用run()方法)。如果调用run()方法相当于调用普通方法,是单线程

public static void main(String[] args) {
        //创建MyThread实例。并调用start方法来启动线程。
        MyThread t1 = new MyThread();
        t1.start();//作用:1:开启一个线程,2:自动去调用run方法。
        //t1.run();//方法的调用。
        //主线程的循环。
        for(int i=0;i<100;i++){
            System.out.println("MainThread---"+i);
        }
    }
}
// 写一个Thread类的子类,重写run方法
class MyThread extends Thread {
    // 重写run:你需要线程干什么,就在run方法里写什么。
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println("MyThread1"+"---"+i);
        }
    }  

实现接口的方式:实现Runnable接口,重写run方法

public class TestTreadDemo2 {
    public static void main(String[] args) {
        //创建Runnable对象
        MyRunnable mr = new MyRunnable();
        //再将实例传给Thread的构造方法。
        Thread t = new Thread(mr);//执行重写的run方法。即MyRunnable类重写的run方法。
        t.start();//启动线程。执行run方法。
        for(int i=0;i<100;i++){
            System.out.println("main----"+i);
        }      
    }
}
class MyRunnable implements Runnable{
    @Override
    public void run() {
        for(int i=0;i<100;i++){
            System.out.println("myrunnable----"+i);
        }     
    }  
    }

建议使用接口的方式创建线程
好处:
1、可以避免由于Java单继承带来的局限性。
2、 适合多个相同程序的代码去处理同一个资源的情况,把线程同程序的代码,数据有效分离,较好的体现了面向对象的设计思想。

继承和接口的区别:
1、java中只能单继承,但是可以多实现,所以建议使用实现接口的方式。
2、如果继承和接口都实现需求,那么建议使用接口的方式
3、当多个线程对同一个资源进行操作的时候,只能使用实现接口的方式。

多线程的数据安全问题
出现原因
1、多个线程
2、对同一资源进行操作。(共享数据)
3、对同一资源的操作有多条语句。(多条语句操作共享数据)
总的来说。当多个线程对同一资源进行操作时,由于cpu的随机性,操作同一个资源的多条语句被分开执行。
解决办法:
让操作同一个资源的多条语句在同一个时刻只能被一个线程执行。

java提供了一个同步机制:synchronized
同步机制的原理:同步锁
让操作同一个资源的多条语句在某个时刻只能被一个线程执行,执行完后才能被其他线程执行。

class Person extends Thread{
    public static int sum = 0;
    public static Object obj = new Object();
    @Override
    public void run() {      
        for(int i=0;i<3;i++){          
            //同步代码块。执行同步代码块的条件:1:获得cpu,2:获得同步锁。
            synchronized (obj) {//要保证所有的线程用的是同一把锁。锁就是一个对象。
                sum = sum+100;//B sum=100,A sum=200,
                try {
                    Thread.sleep(10);//没有交出锁。
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName()+"存了100元,现有"+sum);               
            }//释放锁。
        }
    }
}  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值