线程 小记

创建线程的三种方法:

1:在类中继承Thread类,并重写run方法

2:new一个Thread对象,然后再实现Runnable接口,重写一个匿名内部类run;这个方法没有返回值

3: new一个FutureTask类,并在其中实现Callobel接口,重写call方法

public static void method6() {
        Dog dog = new Dog();//new 一个类
        FutureTask<Integer> futureTask = new FutureTask<>(new Callable<Integer>() {//new一个futureTask对象,在其中实现Callable接口,重写接口中的call方法
            @Override
            public Integer call() throws Exception {
                Integer i=0;
                for(;i<100;i++){
                    System.out.println(Thread.currentThread().getName()+"循环了第"+i+"遍");
                }
                return i;
            }
        });//FutureTask是一个Runnable,可以放进Tread中
        //放进去就表示Tread线程中运行着FutureTask的对象中重写的方法
        Thread thread = new Thread(futureTask);
        thread.start();
        Integer a = null;
        try {
            a = futureTask.get();//这是一个阻塞方法,等线程任务执行完成才会返回值,
            //当get方法执行完后才会执行之后的代码;
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
        System.out.println(a);
        Thread thread2;
        thread2 = new Thread(new Runnable() {//用来和thread进行对比的线程,
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName()+"线程开始运行");
            }
        });
        thread2.start();
    }

Thread类中常用的方法

1、currentThread :获得当前Thread类对象;可以直接将此方法看作类对象,该方法后面可以直接跟其他方法,比如currentThread.getName();就可以获得当前Thread类对象的对象名;

2、join:跟在Thread对象名后面,如thread.join ,代表当前线程必须等待thread线程执行完毕后才能继续执行;

public static void method7(){
        Thread thread1=new Thread(new Runnable() {
            @Override
            public void run() {
                for(int i=0;i<20;i++){
                    System.out.println("方法一:"+i);
                }
            }
        });
        Thread thread2=new Thread(new Runnable() {
            @Override
            public void run() {
                for(int i=0;i<20;i++){
                    System.out.println("方法二:"+i);
                    try {
                        thread1.join();//此方法表示让thread先执行完;
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        });
        thread1.start();
        thread2.start();
    }

多线程安全问题

java的每个线程都有自己的工作空间,线程的工作内存是互不干扰的,是相互独立的,县城内不的方法中出现的局部变量都在工作内存中存储,但线程都可以访问主存(共享内存)的空间

当多个线程同时访问共享内存的数据时才会设计到数据安全问题

解决方法

关键字:synchronized

synchronized可以加在方法声明处:

表示当前线程想要去执行这个方法必须获得当前对象的对象锁,当方法执行完后会自动释放对象锁,或者当方法遇到错误时也会自动释放对象锁,在遇到错误之前的代码会正常执行和存储值;

synchronized也可以加在方法体内部:

当synchronized加在方法体内部时,只能锁住同步代码块内部的代码,在同步代码块内部的代码执行完毕后会立刻释放对象锁

使用synchronized的注意点

如果synchronized写在了静态方法中,需要获得类对象的对象锁

下面的代码method7是将synchronized关键字写在了静态方法内部,

method8是将synchronized关键字写在了静态方法声明处,

public static void method7(){
        synchronized(Dog.class){
            System.out.println("运行了Dog类中的静态方法");
        }
    }
    
    public synchronized static void method6(){
        System.out.println("运行了Dog类中的静态方法");
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值