• Java 多线程


    一、java创建多线程的两种方式

      一种是实现runnable接口,一种是继承自Thread类。都是通过start启动一个新线程,

    public class HelloRunnable implements Runnable {
    
        public void run() {
            System.out.println("Hello from a thread!");
        }
    
        public static void main(String args[]) {
            (new Thread(new HelloRunnable())).start();
        }
    
    }
    public class HelloThread extends Thread {
    
        public void run() {
            System.out.println("Hello from a thread!");
        }
    
        public static void main(String args[]) {
            (new HelloThread()).start();
        }
    
    }

    二、sleep 和 join 方法

       sleep是Thread类的静态方法,为了让一些线程获得一段沉睡时间,在这个过程中不会释放对象锁。

      join也是Tread类的静态方法, 使得当前运行的进程马上停止下来,开始运行调用join的线程。join()可以传入时间,表示在该时间段内运行t线程,如果超出该时间则表示join这个方法失效,继续同时运行主线程和t线程。

      这两个方法都必须在线程start之后调用才起作用,并且需要catch InterruptedException.

    public class MyThread {
        
        public static void main(String[] args) throws InterruptedException{
            TestThread t = new MyThread.TestThread();
            t.start();
            t.join();
            for (int i = 0 ; i < 1000 ;i++)
            {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                System.out.print(i + " Main it's OK !
    " );
            }
            
        }
        
        public static class TestThread extends Thread{
            @Override
            public void run() {
                // TODO Auto-generated method stub
                for (int i = 0 ; i < 1000 ;i++)
                {
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    
                    System.out.print(i + " subClass it's OK !
    " );
                }
            }
        }
    
    }

    三、线程同步

      当多个线程对同一个类实例进行操作时,就可能出现数据异常,如多个售票员同时售票的问题。此时就需要开发者处理数据同步的问题,即为类中的方法或对象添加synchronized关键字。第一种可以为方法添加synchronized关键字,第二种方式括号中的内容可为任意对象,但不能为基本数据类型如(int , float , double等)。

      synchronized获得的锁都是对象锁,当某一线程运行到synchronized标记的方法获得该锁后,其他线程也不能执行该实例其他带有synchronized关键字的方法。

      如果某个静态方法是synchronized ,那么锁的范围则是类,即所有的静态synchronized 方法和字段都受到该锁的限制。

    public synchronized void increment() {
            c++;
        }
    synchronized(this){
                
            }

       括号中为相同对象的同步代码块共享一个对象锁。

    public class MsLunch {
        private long c1 = 0;
        private long c2 = 0;
        private Object lock1 = new Object();
        private Object lock2 = new Object();
    
        public void inc1() {
            synchronized(lock1) {
                c1++;
            }
        }
    
        public void inc2() {
            synchronized(lock2) {
                c2++;
            }
        }
    }

    四、wait, notify,notifyAll

      wait函数是object类的函数,要解决的问题是线程间的同步,该过程包含了同步锁的获取和释放,调用wait方法将会将调用者的线程挂起,直到其他线程调用同一个对象的notify方法才会重新激活调用者。只能在同步控制方法或同步块中调用wait()、notify()和notifyAll()。如果在非同步的方法里调用这些方法,在运行时会抛出IllegalMonitorStateException异常。

  • 相关阅读:
    解决:vue/nodeprecatedvbindsync
    clearValidate elementui为什么没效果
    vue state vuex使用
    【转】解决iframe使用postMessage传值addEventListener未接收到却收到webpackwarning的问题
    elementui中eltable 显示空白 不显示
    在vue中使用lottie动画
    装饰模式(Decorator)
    模版方法(Template Method)
    Redis数据类型、Redis列表命令
    RabbitMQ、ErLang下载、RabbitMQ下载
  • 原文地址:https://www.cnblogs.com/xuexue-bit/p/5139809.html
Copyright © 2020-2023  润新知