Java教程

Java核心编程总结(四、异常与线程),Java基础语法教学视频

本文主要是介绍Java核心编程总结(四、异常与线程),Java基础语法教学视频,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
// 启动后的ThreadDemo当成一个进程。

// main方法是由主线程执行的,理解成main方法就是一个主线程

public static void main(String[] args) {

    // 3.创建一个线程对象

    Thread t = new MyThread();

    // 4.调用线程对象的start()方法启动线程,最终还是执行run()方法!

    t.start();

    

    

    for(int i = 0 ; i < 100 ; i++ ){

        System.out.println("main线程输出:"+i);

    }

}

}

// 1.定义一个线程类继承Thread类。

class MyThread extends Thread{

// 2.重写run()方法

@Override

public void run() {

    // 线程的执行方法。

    for(int i = 0 ; i < 100 ; i++ ){

        System.out.println("子线程输出:"+i);

    }

}

}



### []( )1.5.2实现Runnable接口



1.  创建一个线程任务类实现`Runnable`接口

    

2.  重写`run()`方法

    

3.  创建一个**线程任务对象**(注意:线程任务对象不是线程对象,只是执行线程的任务的)

    

    ```

    Runnable target = new MyRunnable();

    

    ```

4.  把线程任务对象包装成线程对象,且可以指定线程名称

    

    ```

    // Thread t = new Thread(target);

    Thread t = new Thread(target,"1号线程");

    

    ```

5.  调用线程对象的`start()`方法启动线程

    



public class ThreadDemo {

public static void main(String[] args) {

    // 3.创建一个线程任务对象(注意:线程任务对象不是线程对象,只是执行线程的任务的)

    Runnable target = new MyRunnable();

    // 4.把线程任务对象包装成线程对象.且可以指定线程名称

    // Thread t = new Thread(target);

    Thread t = new Thread(target,"1号线程");

    // 5.调用线程对象的start()方法启动线程

    t.start();



    Thread t2 = new Thread(target);

    // 调用线程对象的start()方法启动线程

    t2.start();



    for(int i = 0 ; i < 10 ; i++ ){

        System.out.println(Thread.currentThread().getName()+"==>"+i);

    }

}

}

// 1.创建一个线程任务类实现Runnable接口。

class MyRunnable implements Runnable{

// 2.重写run()方法

@Override

public void run() {

    for(int i = 0 ; i < 10 ; i++ ){

        System.out.println(Thread.currentThread().getName()+"==>"+i);

    }

}

}



#### []( )1.5.2.1Thread的构造器



*   `public Thread(){}`

*   `public Thread(String name){}`

*   `public Thread(Runnable target){}`:分配一个新的Thread对象

*   `public Thread(Runnable target,String name)`:分配一个新的Thread对象,且可以指定新的线程名称



#### []( )1.5.2.1优缺点



缺点:代码复杂一点



优点:



*   线程任务类只是实现了`Runnable`接口,可以继续继承其他类,而且可以继续实现其他接口(避免乐单继承的局限性)

    

*   同一个线程任务对象可以被包装成多个线程对象

    



### []( )1.5.3实现Callable接口



1.  定义一个线程任务类实现`Callable`接口,申明线程返回的结果类型

2.  重写线程任务类的`call`方法,这个方法可以直接返回执行的结果

3.  创建一个`Callable`的线程任务对象

4.  把`Callable`的线程任务对象包装成一个未来任务对象

5.  把未来任务对象包装成线程对象

6.  调用线程的`start()`方法启动线程



public class ThreadDemo {

public static void main(String[] args) {

    // 3.创建一个Callable的线程任务对象

    Callable call = new MyCallable();

    // 4.把Callable任务对象包装成一个未来任务对象

    //      -- public FutureTask(Callable<V> callable)

    // 未来任务对象是啥,有啥用?

    //      -- 未来任务对象其实就是一个Runnable对象:这样就可以被包装成线程对象!

    //      -- 未来任务对象可以在线程执行完毕之后去得到线程执行的结果。

    FutureTask<String> task = new FutureTask<>(call);

    // 5.把未来任务对象包装成线程对象

    Thread t = new Thread(task);

    // 6.启动线程对象

    t.start();



    for(int i = 1 ; i <= 10 ; i++ ){

        System.out.println(Thread.currentThread().getName()+" => " + i);

    }



    // 在最后去获取线程执行的结果,如果线程没有结果,让出CPU等线程执行完再来取结果

    try {

        String rs = task.get(); // 获取call方法返回的结果(正常/异常结果)

        System.out.println(rs);

    }  catch (Exception e) {

        e.printStackTrace();

    }



}

}

// 1.创建一个线程任务类实现Callable接口,申明线程返回的结果类型

class MyCallable implements Callable{

// 2.重写线程任务类的call方法!

@Override

public String call() throws Exception {

    // 需求:计算1-10的和返回

    int sum = 0 ;

    for(int i = 1 ; i <= 10 ; i++ ){

        System.out.println(Thread.currentThread().getName()+" => " + i);

        sum+=i;

    }

    return Thread.currentThread().getName()+"执行的结果是:"+sum;

}

}



#### []( )1.5.4优劣点



优点:全是优点



[]( )1.6线程的常用API

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



Thread 类的 API



1.  `public void setName(String name)`: 给当前线程取名字

2.  `public void getName()`: 获取当前线程的名字

    *   线程存在默认名称,子线程的默认名称是:Thread - 索引

    *   主线程的默认名称是:main

3.  `public static Thread currentThread()`: 获取当前线程对象,这个代码在哪个线程中,就得到哪个线程对象

4.  `public static void sleep(long time)`:让当前线程休眠多少毫秒再继续执行

5.  `public Thread(String name)`:创建对象并取名字



* * *



public class ThreadDemo {

// 启动后的ThreadDemo当成一个进程。

// main方法是由主线程执行的,理解成main方法就是一个主线程

public static void main(String[] args) {

    // 创建一个线程对象

    Thread t1 = new MyThread();

    t1.setName("1号线程");

    t1.start();

    //System.out.println(t1.getName()); // 获取线程名称



    Thread t2 = new MyThread();

    t2.setName("2号线程");

    t2.start();

    //System.out.println(t2.getName());  // 获取线程名称



    // 主线程的名称如何获取呢?

    // 这个代码在哪个线程中,就得到哪个线程对象。

    Thread m = Thread.currentThread();

    m.setName("最强线程main");

    //System.out.println(m.getName()); // 获取线程名称



    for(int i = 0 ; i < 10 ; i++ ){

        System.out.println(m.getName()+"==>"+i);

    }

}

}

// 1.定义一个线程类继承Thread类。

class MyThread extends Thread{

// 2.重写run()方法

@Override

public void run() {

    // 线程的执行方法。

    for(int i = 0 ; i < 10 ; i++ ){

        System.out.println(Thread.currentThread().getName()+"==>"+i);

    }

}

}



* * *



线程休眠api



public class ThreadDemo02 {

public static void main(String[] args) {

    for(int i = 0 ; i < 10 ; i++ ) {

        System.out.println(i);

        try {

            // 项目经理让我加上这行代码

            // 如果用户交钱了,我就去掉。

            Thread.sleep(1000); // 让当前线程休眠1s.

        } catch (Exception e) {

            e.printStackTrace();

        }

    }

}

}



* * *



通过Thread类的有参构造器为当前线程对象取名字



public class ThreadDemo03 {

// 启动这个类,这个类就是进程,它自带一个主线程,

// 是main方法,main就是一个主线程的执行!!

public static void main(String[] args) {

    Thread t1 = new MyThread02("1号线程");

    t1.start();



    Thread t2 = new MyThread02("2号线程");

    t2.start();



    Thread.currentThread().setName("主线程");

    for(int i = 0 ; i < 10 ; i++ ) {

        System.out.println(Thread.currentThread().getName()+" => "+i);

    }

}

}

// 1.定义一个线程类继承Thread。线程类并不是线程对象,用来创建线程对象的。

class MyThread02 extends Thread{

public MyThread02(String name) {

    //  public Thread(String name):父类的有参数构造器

    super(name); // 调用父类的有参数构造器初始化当前线程对象的名称!

}



// 2.重写run()方法

@Override

public void run() {

    for(int i = 0 ; i < 10 ; i++ ) {

        System.out.println(Thread.currentThread().getName()+" => "+i);

    }

}

}



[]( )1.7线程安全

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



线程安全问题:多个线程同时操作同一个共享资源的时候可能会出现线程安全问题



[]( )1.7线程同步\_同步代码块

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



*   **线程同步的作用**:就是为了解决线程安全问题,让多个线程实现先后依次访问共享资源,这样就解决了安全问题

    

*   **线程安全**:多个线程同时操作同一个共享资源的时候可能会出现线程安全问题

    

*   **线程同步的做法**:加锁(就是把共享资源进行上锁,每次只能一个线程进入访问完毕以后,其他线程才能进来)

    

*   **线程同步的方法**:

    

    *   同步代码块

    *   同步方法

    *   `lock` 显示锁



**同步代码块作用**:是把出现线程安全问题的核心代码给上锁,每次只能一个线程进入,执行完毕之后自动解锁,其他线程才可以进来执行



// 格式

synchronized(锁对象){

// 访问共享资源的核心代码    

}



*   在实例方法中建议用`this`作为锁对象

*   在静态方法中建议用`类名.class`字节码作为锁对象



[]( )1.8线程同步\_同步方法

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



**作用**:把出现线程安全问题的核心方法给锁起来,每次只能一个线程进入访问,其他线程必须在方法外面等待



**用法**:直接给**方法**加上一个修饰符 `synchronized`



public synchronized void 方法名(){

}



原理:同步方法的原理和同步代码块的底层原理其实是完全一样的,只是同步方法是把整个方法的代码都锁起来,同步方法其实底层也有锁对象的。



*   如果方法是实例方法:同步方法默认用 `this`作为锁对象

*   如果方法是静态方法:同步方法默认用`类名.class` 作为锁对象



[]( )1.9线程同步\_lock显示锁

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



Lock锁也称同步锁,加锁与释放锁方法化了,如下



*   `public void lock()`: 加同步锁

*   `public void unlock()`: 释放同步锁



// 创建一把锁对象

private final Lock lock = new ReentrantLock();

这篇关于Java核心编程总结(四、异常与线程),Java基础语法教学视频的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!