java 线程 1

写在前面

1、单线程的创建

1 继承Thread类 (里面实际上也是实现的Runnable接口)
2 实现runable接口 (没返回值)
3 实现callable接口 (有返回值)

1.1、继承Thread类使用示例

class Mythread extends Thread{
    @Override
    public void run() {
        for(int i=0;i<100;i++){
            if(i%2==0){
                System.out.println(i);
            }
        }
    }
}

调用

    public static void main(String[] args) {
        // 用start()来启动线程,此时会出现异步执行的效果。
        // 用run()来启动线程,就不是异步执行了,而是同步执行,不会达到使用线程的意义。
        new Thread1().start();

    }

或者直接这样

    public static void main(String[] args) {
        new Thread(){
            @Override
            public void run() {
                for(int i=0;i<100;i++){
                    if(i%2==0){
                        System.out.println("1222:"+i);
                    }
                }
            }
        }.start();
    }

1.2、实现runable接口使用示例

public class Thread2 implements Runnable{
    private int ticket;
    public Thread2(int ticket){
        this.ticket=ticket;
    }
    @Override
    public void run(){
        while (ticket>0){
            ticket--;
            System.out.println("剩余"+ticket+"张票");
        }
    }
}

调用

    public static void main(String[] args) {
        Runnable r = new Thread2(100);
        new Thread(r).start();
    }

或者直接这样

    public static void main(String[] args) {
        Runnable r = new Runnable() {
            private int ticket = 100;
            @Override
            public void run() {
                while (ticket > 0) {
                    ticket--;
                    System.out.println("剩余" + ticket + "张票");
                }
            }
        };
        new Thread(r).start();
    }

1.3、实现callable接口使用示例

public class Thread3 implements Callable {
    @Override
    public Object call() throws Exception {
        for(int i=0;i<100;i++){
            if(i%2==0){
                System.out.println(i);
            }
        }
        return "ok";
    }
}

调用

    public static void main(String[] args) {
        Thread3 r = new Thread3();
        FutureTask futureTask = new FutureTask(r);
        Thread t1 = new Thread(futureTask);
        t1.start();
        try {
            //get()方法的返回值即为FutureTask构造器参数Callable实现类重写的call()的返回值
            Object rsl = futureTask.get();
            System.out.println(rsl);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }

    }

2、sleep和wait的区别

方法名区别
sleep()暂停一段时间后恢复,没有释放锁,必须抛异常。用于当前线程
wait()需要被唤醒,释放了锁,必须抛异常。用于多线程间通信

2.1、使用wait需要注意

使用 wait 方法则必须放在 synchronized 块里面,同样需要捕获 InterruptedException 异常,并且需要获取对象的锁。

synchronized (lock){
    try {
        lock.wait();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

而且 wait 还需要额外的方法 notify/ notifyAll 进行唤醒,它们同样需要放在 synchronized 块里面,且获取对象的锁。

synchronized (lock) {
    // 随机唤醒
    lock.notify();
// 唤醒全部
    lock.notifyAll();
}

当然也可以使用带时间的 wait(long millis) 方法,时间一到,无需其他线程唤醒,也会重新竞争获取对象的锁继续执行。

2.2、释放锁

Object lock = new Object();
synchronized (lock) {
    try {
        lock.wait(3000L);
        Thread.sleep(2000L);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

如上,wait 可以释放当前线程对 lock 对象锁的持有,而 sleep 则不会。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值