Loading

java多线程的基本使用

多线程的基本使用

创建线程的两种方式

  1. 继承Thread类

    public class MyThread extends Thread{
        @Override
        public void run() {
            System.out.println(getName()+"--->run");
        }
    
        public static void main(String[] args) throws InterruptedException {
            Thread a = new MyThread();
            Thread b = new MyThread();
            a.start();
            b.start();
            a.join();
            b.join();
        }
    }
    
  2. 实现Runnable接口

    public static void main(String[] args) {
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                System.out.println("i'm runnable");
            }
        };
        new Thread(runnable).start();
    }
    

    简写:

    public static void main(String[] args) {
        new Thread(()->{
            System.out.println("i'm simple");
        }).start();
    }
    

线程同步

如果不设置同步

class MyRunnableImpl implements Runnable{
    private int x = 0;
    @Override
    public void run() {
        for(int i =0;i<10000;i++){
            x = x+1;
            x = x-1;
        }
    }

    public int getX() {
        return x;
    }
}

public class SyncTest {
    public static void main(String[] args) throws InterruptedException {
        MyRunnableImpl runnable = new MyRunnableImpl();
        Thread thread = new Thread(runnable);
        Thread thread2 = new Thread(runnable);
        thread.start();
        thread2.start();
        thread.join();
        thread2.join();
        System.out.println(runnable.getX());

    }

}

此次程序运行结果:28

但是根据程序的逻辑来讲应该是0,而结果不是0的原因就是没有同步

通过synchronized关键字来设置同步

class MyRunnableImpl implements Runnable{
    private int x = 0;
    @Override
    public void run() {
        for(int i =0;i<10000;i++){
            synchronized (this){
                x = x+1;
                x = x-1;
            }
        }
    }

    public int getX() {
        return x;
    }
}

public class SyncTest {
    public static void main(String[] args) throws InterruptedException {
        MyRunnableImpl runnable = new MyRunnableImpl();
        Thread thread = new Thread(runnable);
        Thread thread2 = new Thread(runnable);
        thread.start();
        thread2.start();
        thread.join();
        thread2.join();
        System.out.println(runnable.getX());

    }

}

运行结果为0

synchronized关键字还可以加在函数上表示对函数体的内容进行加锁

class MyRunnableImpl implements Runnable{
    private int x = 0;
    @Override
    public synchronized void run() {
        for(int i =0;i<10000;i++){
                x = x+1;
                x = x-1;
        }
    }

    public int getX() {
        return x;
    }
}

public class SyncTest {
    public static void main(String[] args) throws InterruptedException {
        MyRunnableImpl runnable = new MyRunnableImpl();
        Thread thread = new Thread(runnable);
        Thread thread2 = new Thread(runnable);
        thread.start();
        thread2.start();
        thread.join();
        thread2.join();
        System.out.println(runnable.getX());

    }

}

不需要synchronized的操作

JVM规范定义了几种原子操作:

  • 基本类型(longdouble除外)赋值,例如:int n = m
  • 引用类型赋值,例如:List<String> list = anotherList

longdouble是64位数据,JVM没有明确规定64位赋值操作是不是一个原子操作,不过在x64平台的JVM是把longdouble的赋值作为原子操作实现的。

单条原子操作的语句不需要同步

java多线程——线程通信wait与notify

posted @ 2021-03-25 22:21  克豪  阅读(67)  评论(0)    收藏  举报