Java 线程

53 阅读2分钟

线程

线程和进程

线程:线程就是一条执行线索,多个线程是并发的运行着。

进程:是一个运行在内存中的程序,它有一块独立的内存空间。一个进程可能包含一个或多个线程。

Java当中的main函数就是一个主线程,迅雷下载是多线程的。

线程的创建方式

继承Thread类

1、继承Thread类
2、重写run方法(线程在执行的时候就是在执行线程类中的run方法中的代码)
3、创建线程对象
4、调用start方法

//1、继承Thread类
public class ThreadDemo1 extends Thread{

    int i;
    int j=0;
    public ThreadDemo1(int i){
        this.i = i;
    }
    //        2、重写run方法(线程在执行的时候就是在执行线程类中的run方法中的代码)
    @Override
    public void run() {
        for (; j < 20; j++) {
            System.out.println(i + "hello" + Thread.currentThread().getName() + ":" +j);
        }
    }

    public static void main(String[] args) {
        //        3、创建线程对象
        ThreadDemo1 c = new ThreadDemo1(1);
        ThreadDemo1 c2 = new ThreadDemo1(1);
        //        4、调用start方法
        c2.start();
        c.start();
    }
}

实现Runnable接口

1、实现Runnable接口
2、重写run方法
3、创建线程对象(Thread),并且传入Runnable对象
4、在通过线程对象调用start方法


//Runnable更容易的实现数据共享

//1、实现Runnable接口
public class ThreadDemo2 implements Runnable{
    int i;
    int j = 0;
    public ThreadDemo2(int i){
        this.i = i;
    }

    //        2、重写run方法
    @Override
    public void run() {
        for (; j < 20; j++) {
            System.out.println(i + "hello" + Thread.currentThread().getName() + ":" + j);
        }

    }

    public static void main(String[] args) {
        //        3、创建线程对象(Thread),并且传入Runnable对象
        ThreadDemo2 c = new ThreadDemo2(1);
        Thread t1 = new Thread(c);
        Thread t2 = new Thread(c);

        //        4、在通过线程对象调用start方法
        t1.start();
        t2.start();
    }
}

实现Callable接口

1、实现Callable接口(需要定义返回值类型),重写call方法(需要抛出异常)
2、创建实现Callable接口的对象
3、建执行服务,提交执行,获取结果
4、关闭服务

public class MyThread implements Callable {
    //重写Callable接口
    @Override
    public Object call() throws Exception {
        return "重写call方法";
    }

    public static void main(String[] args) throws ExecutionException, InterruptedException, ExecutionException {
        //创建实现Callable接口的对象
        MyThread mythread = new MyThread();
        //创建线程池
        ExecutorService service = Executors.newFixedThreadPool(1);
        //提交执行
        Future<String> result = service.submit(mythread);
        //获取结果
        String serviceresult = result.get();
        //输出返回结果
        System.out.println(serviceresult);
        //关闭服务
        service.shutdownNow();
    }
}

创建线程池

1、创建线程池
2、调用execute方法并传入参数(Runnable或Thread接口对象)来启动线程
3、关闭服务

public class MyThread2 {
    public static void main(String[] args) {
        //创建线程池
        ExecutorService service = Executors.newFixedThreadPool(1);
        //调用execute方法启动线程
        service.execute(()-> System.out.println("创建线程池启动线程"));
        //关闭服务
        service.shutdown();
    }
}

synchronized

三个窗口卖票


//Runnable更容易的实现数据共享
//synchronized  同一时刻只能允许一个线程进入
    
//1、实现Runnable接口
public class ThreadDemo4 implements Runnable{
    private int i = 100;
    Object obj = new Object();
    //        2、重写run方法
    @Override
    public void run() {
        sell();
    }

    //在方法上声明synchronized锁
    public synchronized void sell(){
        try {
            while (i > 0){
                i--;
                int j =100-i;
                System.out.println("当前已售出"+j+"张票;" + "还剩下"+i+"张票;" + Thread.currentThread().getName() );
                Thread.sleep(100);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }


    public static void main(String[] args) {
        //        3、创建线程对象(Thread),并且传入Runnable对象
        ThreadDemo4 c = new ThreadDemo4();
        Thread t1 = new Thread(c);
        Thread t2 = new Thread(c);
        Thread t3 = new Thread(c);

        //优先级默认是5,范围设置是0-10,优先级设置以后,并不代表这个线程一定会优先执行,它只是多了一个优先权
        t2.setPriority(10);

        t1.setName("线程1");
        t2.setName("线程2");
        t3.setName("线程3");
        //        4、在通过线程对象调用start方法
        t1.start();
        t2.start();
        t3.start();

    }
}

死锁

待定。。。。

参考:
Java创建线程的四种方式