Java多线程基础知识Tread|Runnable

1 篇文章 0 订阅
1 篇文章 0 订阅

进程

具有一定独立功能的程序关于某个数据集合上的一次运行活动;

线程

线程是最小的执行单元,而进程由至少一个线程组成。

关系

进程和线程的关系:

(1)一个线程只能属于一个进程,而一个进程可以有多个线程,但至少有一个线程。

(2)资源分配给进程,同一进程的所有线程共享该进程的所有资源。

(3)CPU分给线程,即真正在CPU上运行的是线程。

多线程的好处

  • 效率高
  • 多个线程之间互不影响

多线程的调度

  • 分时调度(轮流使用cpu)
  • 抢占式调度(享有优先级,优先级高的先使用cpu)

创建多线程

  • 继承Thread类并重写run⽅法;
  • 实现Runnable接⼝的run⽅法;

Tread常用方法

  • 获得名称
public class MyThread extends Thread {

    @Override
    public void run() {
        // 获取线程方法的名字 方法一
        // String threadName = super.getName();
        // System.out.println(threadName);
        // 方法二  使用静态方法currentThread
        Thread thread = currentThread();
        System.out.println(thread);
        String name = thread.getName();
        System.out.println(name);
    }
}

// 测试
public class MyThreadTest {

    public static void main(String[] args) {

        MyThread myThread = new MyThread();
        myThread.start();

        new MyThread().start();
        new MyThread().start();
        new MyThread().start();

        //main 线程名
        System.out.println("主线程"+Thread.currentThread().getName());

    }
}
  • 设置线程名称
<!--方法一:调用父类的构造方法可以设置-->
public class MyThread extends Thread {
    
    public MyThread(String str) {
        super(str);
    }

    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName());
    }
}

<!--方法二:-->

public class MyThreadTest {

    public static void main(String[] args) {
        MyThread myThread = new MyThread();
        myThread.setName("zidingyi");
        myThread.start();

    }
}
public class MyThread extends Thread {
    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName());
    }
}


  • sleep 静态方法可以直接使用类名.方法名调用

Runnable

public class RunnableImpl implements Runnable{

    /** 实现Runnable接口方式
     * 1.创建Runnable接口实现类,Runnable中只有一个run方法
     * 2.在实现类中重写run方法
     * 3.创建Thread对象,在构造方法中传入Runnable实现类对象
     * 4.调用Thread的start方法,开启新的线程
     * 
     */
    @Override
    public void run() {

        for(int i=0;i<20;i++){
            System.out.println(Thread.currentThread().getName());
        }

    }
}

--------------------------------------------


public class MyRunnable {

    public static void main(String[] args) {

        RunnableImpl runnable = new RunnableImpl();
        new Thread(runnable).start();
        //主线程
        for(int i=0;i<20;i++){
            System.out.println(Thread.currentThread().getName());
        }
        
    }
}


创建新线程的两种方式的区别

实现Runnable创建多线程程序的好处

  • 避免了单继承的局限性,一个类只能继承一个类,继承了Thread类就不能继承其他类
  • 增强了程序的扩展性,降低了程序的耦合性(解耦),实现Runnable接口的方式,把设置线程任务和开启新线程进行了分离

匿名内部类实现多线程

public class InnerClassTest {


    public static void main(String[] args) {

        //第一种方式
        new Thread(){
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName()+"-----------方式一");
            }
        }.start();

        // 第二种方式
        Runnable runnable2 = new Runnable() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName() + "-----------方式二");
            }
        };
        new Thread(runnable2).start();

        // 第三种方式:简化了第二种方式
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName() + "-----------方式三");
            }
        }).start();
    }


}

线程不安全

解决方式

  • 设置同步锁(同步代码块)创建锁对象使用synchronized包括代码块 代价:降低了程序的效率
public class SaleTicketsImpl implements Runnable{

    private int ticket=100;
    
    Object obj =new Object();
    @Override
    
    public void run() {

        while (true){
            synchronized (obj){
                if (ticket>0){
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName()+"正在卖第"+ticket);
                    ticket--;
                }
            }
        }
    }
}

public class Test {


    public static void main(String[] args) {

        SaleTicketsImpl saleTickets = new SaleTicketsImpl();
        Thread thread1 = new Thread(saleTickets);
        Thread thread2 = new Thread(saleTickets);
        Thread thread3= new Thread(saleTickets);
        thread1.start();
        thread2.start();
        thread3.start();
    }
}


  • 同步方法 synchronized修饰方法,方法中放访问共享数据
public class SaleTicketsImpl implements Runnable {

    private int ticket = 100;
    @Override
    public void run() {

        while (true) {
            payTickets();
        }
    }
    public synchronized void payTickets() {

        if (ticket > 0) {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + "正在卖第" + ticket);
            ticket--;
        }
    }
}
  • Lock锁 可以获取锁和释放锁

     1.在成员位置创建一个ReentrantLock对象

     2.在可能出现线程安全的代码前调用Lock接口中的方法获取锁

     2.在可能出现线程安全的代码前调用Lock接口中的方法释放锁
public class SaleTicketsImpl implements Runnable {

    private int ticket = 100;

    /*1.创建Lock对象*/

    Lock l1 = new ReentrantLock();

    @Override
    public void run() {

        while (true) {
            // 2.获取锁
            l1.lock();
            try {
                if (ticket > 0) {
                    Thread.sleep(10);
                    System.out.println(Thread.currentThread().getName() + "正在卖第" + ticket);
                    ticket--;
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                //3.释放锁
                l1.unlock();
            }
        }
    }
}


  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值