线程和进程、线程的同步和锁

1、什么是进程

是独立的运行程序,

例如一个电脑软件,启动起来后就是一个进程

进程具有

1、独立性:各个进程之间是相互的独立的互不影响的。

2、互斥性:每个软件系统都会分配一个独立端口号,两个相同的端口号只能启动一个程序,先启动的先得

2、什么是线程

进程是由多个或者一个线程组成的。每个进程至少得有一个线程的支撑。

例如:一个进程(QQ),qq里面很多个线程在执行。线程的执行支撑起来了进程的执行。

进程包含了线程,线程是组成进程的最小基本单位   

线程的特征:

1、抢占式运行的【重要】

  CPU在执行的时候,按照时间片来执行的,单位的时间片是抢占式执行的

2、资源共享性

一个线程可以共享当前CPU, 网卡等

java程序:一个java程序就是一个进程,一个java程序Demo1里面至少两个线程:一个main主函数线程,一个jvm垃圾回收器线程

3、线程和进程的区别【面试题】

进程是一个应用程序,是独立的
线程是进程中最小的基本单位。
把进程比作生产车间,每个流水线就是一个线程
进程有独立性和互斥性
线程有抢占式运行和资源共享特性

 4、并发和并行 

并发:同时发生,轮流交替执行

并行:真正意义上的同时执行

5、创建线程的两种方式【重点】

(创建线程地两种方式
    1.
        继承Thread类
        在main主函数中  实例化Thread的子类,然后调用方法start方法启动线程
    2.
        实现Runnable接口
        实例化Thread类,实现Runnable接口对象的作为Thread的参数,然后调用start方法)

1.  一个是将一个类声明为Thread的子类。这个子类应该重写run方法,然后可以分配并启动子类的实例。

例:

package com.qf.d_yuxi;
class  MyThread10 extends Thread{
    @Override
    public void run() {
        for (int i = 0; i < 500; i++) {
            System.out.println("我是myThread10线程:+" + i );
        }
    }
}
class  MyTread11 extends  Thread{
    @Override
    public void run() {
        for (int i = 0; i < 500; i++) {
            System.out.println("我是myThread11:" + i );
        }
    }
}
public class Demo3 {
    public static void main(String[] args) {
        new MyThread10().start();
        new MyTread11().start();
//        new MyThread10().run();
//        new MyTread11().run();

    }
}

启动线程  使用start方法  在主线程中开启子线程

是抢占式的,随机执行线程的!!!

2.  另一种方法来创建一个线程是声明实现类Runnable接口。 那个类然后实现了run方法。 然后可以分配类的实例(创建类的对象),在创建Thread时作为参数传递,并启动。

package com.qf.d_yuxi;
class  MyThread13 implements Runnable{
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println("MyThread13:" + i );
        }
    }
}
class MyThread14 implements Runnable{
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println("MyThread14:" + i );
        }
    }
}
public class Demo3 {
    public static void main(String[] args) {
//        MyTread13 myTread13 = new MyTread13();
//        Thread thread = new Thread();
//        thread.start();
        new Thread(new MyThread13()).start();
        new Thread(new MyThread14()).start();
        for (int i = 0; i < 100; i++) {
            System.out.println("main主线程:" + i );
        }
    }
}

6、线程下面的几个方法

构造方法

Thread()分配一个新的 Thread对象。 无参构造方法
Thread(Runnable target)分配一个新的 Thread对象。 有参构造
Thread(Runnable target, String name)分配一个新的 Thread对象。并起名字

线程方法:

static Thread

currentThread()返回对当前正在执行的线程对象的引用
StringgetName()返回此线程的名称。
voidsetName(String name)将此线程的名称更改为等于参数 name
intgetPriority()返回此线程的优先级。
voidsetPriority(int newPriority)更改此线程的优先级。
设置优先并不一定优先,只是增加了执行的概率。最小值是1,最大值是10,默认的是5
static voidsleep(long millis)使当前正在执行的线程以指定的毫秒数暂停(暂时停止执行),具体取决于系统定时器和调度程序的精度和准确性。

7、线程的同步和锁

为什么要进行线程的同步?

Java是允许多线程,当多个线程操作同一个资源的时候,会导致得到或者打印的数据不准确。从而发生冲突。咋解决?加同步锁。

class MySycn implements Runnable {
    //卖10张票
    int ticket = 50;
    @Override
    public void run() {
        while (true) {

            if (ticket > 0) {
                //线程1进到循环中了 在没有执行--之前,线程2 进到循环里面
                //ticket  线程1 是50   ticket 线程2也是50

                System.out.println(Thread.currentThread().getName() + "卖出了第" + ticket-- + "票");
            }
        }

    }
}
public class Demo4 {
    public static void main(String[] args) {
        MySycn mySycn = new MySycn();
        Thread thread = new Thread(mySycn, "线程1");
        thread.start();
        Thread thread1 = new Thread(mySycn, "线程2");
        thread1.start();
        Thread thread2 = new Thread(mySycn, "线程3");
        thread2.start();
        //打印出来的数据有重复的数据出现,符合咱们的场景吗?
        //不符合,生活场景的
        //咋解决?
        //对代码加锁:
        //只能保持一个线程进来,其他线程在外面等待。等这个线程结束以后,其他线程再进来
        
    }
}

解决方案:

1、同步方法:使用一个关键字synchronized修饰方法。因为Java对象都有一个内置的锁对象。当使用这个关键字的时候,修饰方法的时候,这个方法就会被锁保护

public synchronized  void run () {

}

但是,对run方法加锁了, 但是出现一家独大的情况。一个线程跑完了所有代码

另外一种解决方法:

2、同步代码块:就是拥有了synchronized 关键字修饰一个语句块。被修饰的语句块会被加锁。从而实现同步。

synchronized  (this) {

}

加锁的目的为了保证数据的准确性。

class SaleTicket implements Runnable {
    private static int ticket = 100;

    @Override
    public void run() {
        while (true) {
            synchronized (this) {
                if (ticket > 0) {

                    System.out.println(Thread.currentThread().getName() + "卖出了第" + ticket + "票");
                    ticket--;

                } else {
                    System.out.println("买完了");
                    break;
                }
            }
        }
    }
}

public class Demo5 {
    public static void main(String[] args) {
        SaleTicket saleTicket = new SaleTicket();
        new Thread(saleTicket, "淘票票").start();
        new Thread(saleTicket, "美团").start();
        new Thread(saleTicket, "猫眼").start();

    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值