• Java多线程


      在Java中,有两种实现多线程的方式:继承Thread类和实现Runnable接口。

    Thread

    此类的定义如下:

      public class Thread extends Object implments Runnable

    构造方法如下:

      Thread(),Thread(Runnable target)  

    静态字段:

      static int MAX_PRIORITY:线程可以具有的最高优先级

      static int MIN_PRIORITY:线程可以具有的最低优先级

      static int NORM_PRIORITY:分配给线程的默认优先级

    主要方法:

      public void start():启动线程,Java虚拟机调用该线程的run方法。

      public static void sleep(long millis) throws InterruptedException:是线程休眠指定的毫秒

    实例

    package com.fuwh.thread;
    
    public class ThreadTest01 {
        public static void main(String[] args) {
            System.out.println("线程最大优先级:"+Thread.MAX_PRIORITY);
            System.out.println("线程最小优先级:"+Thread.NORM_PRIORITY);
            System.out.println("线程默认优先级:"+Thread.MIN_PRIORITY);
            
            Thread t1=new Thread();
            Thread t2=new Thread("线程二");
            t1.setName("线程一");
            System.out.println(t1.getName()+"的优先级:"+t1.getPriority()+";Id:"+t1.getId());
            System.out.println(t2.getName()+"的优先级:"+t2.getPriority()+";Id:"+t2.getId());
        }
    }
    View Code

     实例2

    package com.fuwh.thread;
    
    class MyThread extends Thread{
        private String name;
        public MyThread(String name){
            this.name=name;
        }
        @Override
        public void run() {
            // TODO Auto-generated method stub
            for(int i=0;i<10;i++){
                System.out.println(name+"线程运行  -- "+i);
            }
        }
    }
    
    public class ThreadTest02 {
        public static void main(String[] args) {
            MyThread mt1=new MyThread("线程一");
            MyThread mt2=new MyThread("线程二");
            mt1.start();
            mt2.start();
        }
    }
    View Code

    此时的线程已经实现了交互的运行了。

    Runnable接口

    接口的定义如下:

      public interface Runnable

    此类中只有一个run()方法。使用Runnable接口的对象创建线程的时候,启动该线程,就导致该独立执行的线程会调用该接口中的run()方法。

    实例

    package com.fuwh.thread;
    
    class MyRunnable implements Runnable{
        private String name;
        public MyRunnable(String name){
            this.name=name;
        }
        @Override
        public void run() {
            // TODO Auto-generated method stub
            for(int i=0;i<10;i++){
                System.out.println(name+"线程运行  -- "+i);
            }
        }
    }
    
    public class ThreadTest03 {
        public static void main(String[] args) {
            MyRunnable mt1=new MyRunnable("线程一");
            MyRunnable mt2=new MyRunnable("线程二");
            new Thread(mt1).start();
            new Thread(mt2).start();
        }
    }
    View Code

     

     那么,这两种实现方式有什么区别呢,首先,实现接口可以避免java单继承的问题,

    其次,通过观察可以发现,如果以如下的方式启动多线程呢?

    Runnable接口子类实例 ra=new Runnable接口子类实例 ();
    new Thread(ra).start();
    new Thread(ra).start();

    则此时,两个线程在启动之后调用的都是ra实例的run方法,则可以达到资源共享的目的。

    实例

    package com.fuwh.thread;
    
    class SellTicket implements Runnable{
        private int ticketCount=50;
        @Override
        public void run() {
            // TODO Auto-generated method stub
            for(int i=0;i<50;i++){
                if(this.ticketCount>0){
                    System.out.println("售票一张,余票:"+this.ticketCount--);
                }
            }
        }
    }
    
    public class ThreadTest04 {
        public static void main(String[] args) {
            SellTicket st=new SellTicket();
            new Thread(st,"卖票点1").start();
            new Thread(st,"卖票点2").start();
        }
    }
    View Code

      但是,此时 仍然存在一个问题,倘若只剩最后一张票的时候,线程一去判断,还有一张票,于是准备去执行卖票,这时候线程二来了,发现也还有一张票,也准备去执行卖票,这时候,就会导致线程一和线程二都会去执行卖票操作,导致多卖一张票。

      这时候,就需要引入线程的同步和死锁概念。

    同步与死锁

       在java中,要实现同步有两种方式:同步代码块同步方法

    同步代码块修改上述实例: 

    package com.fuwh.thread;
    
    class SellTicket implements Runnable{
        private int ticketCount=10;
        @Override
        public void run() {
            // TODO Auto-generated method stub
            for(int i=0;i<50;i++){
                synchronized (this) {
                    if(this.ticketCount>0){
                        try {
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                        System.out.println("售票一张,余票:"+this.ticketCount--);
                    }
                }
            }
        }
    }
    
    public class ThreadTest04 {
        public static void main(String[] args) {
            SellTicket st=new SellTicket();
            new Thread(st,"卖票点1").start();
            new Thread(st,"卖票点2").start();
        }
    }
    View Code

     同步方法修改:

    package com.fuwh.thread;
    
    class SellTicket implements Runnable{
        private int ticketCount=10;
        @Override
        public void run() {
            // TODO Auto-generated method stub
            for(int i=0;i<50;i++){
                this.sellTicket();
            }
        }
        public  synchronized void sellTicket(){
            if(this.ticketCount>0){
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                System.out.println("售票一张,余票:"+this.ticketCount--);
            }
        }
    }
    
    public class ThreadTest06 {
        public static void main(String[] args) {
            SellTicket st=new SellTicket();
            new Thread(st,"卖票点1").start();
            new Thread(st,"卖票点2").start();
        }
    }
    View Code

     死锁

       死锁就是说当两个线程在互相等待的时候,就会出现死锁。

  • 相关阅读:
    山寨 《寻找房祖名》
    css3 弹性效果上下翻转demo
    CSS3 Hover 动画特效
    判断一个字符串通过变化字符的位置,是否可以组成回文
    获取多个字符串中的共同字符
    转换为回文的步数
    IOS中图片的一些处理方法
    python django的一点笔记
    一个图片切割的例子
    一个批量修改文件夹中文件名的命令
  • 原文地址:https://www.cnblogs.com/zerotomax/p/6492940.html
Copyright © 2020-2023  润新知