标签:java线程 类对象 总结 stack 静态 启动方式 pre bsp 业务逻辑
如何去定义一个线程?(三种方式)
1.Thread:继承这个类,然后重写run方法;将业务逻辑或任务写到run方法中,然后调用start来启动线程;
2.Runnable: 实现这个接口,然后重写run方法,创建Thread对象将Runnable实现类对象作为参数传递,最后调用start启动线程;
3.Callable<T>:实现这个接口,然后重写Call方法;
---扩展---
面试问题:Runnable和Callable有什么不同?
包;
泛型;
方法;
启动方式;
执行完成之后Runnable结束,Callable没有结束;
多线程并发问题:由于线程之间是有相互抢占资源导致程序出现不符合常理的问题
锁:通过synchonized来锁定一段代码,需要一个对象,锁对象要求是所有的线程都得认识:共享资源、类的字节码
wait()---让当前执行的线程等待,直到被唤醒才会继续执行
notify()---唤醒在等待的线程
通过wait/notify/notifyAll方法来调节线程之间的运行顺序---线程间的相互通信---等待唤醒机制
当调用wait方法的时候,线程会去线程池中等待。而线程池本质上是一个存储线程的队列
---扩展---
面试题总结:wait和sleep有什么区别?
sleep方法需要指定一个沉睡时间,到点自然醒,释放执行权,不释放锁,是一个静态方法,被设计在了Thread类上
wait方法可以指定时间也可以不指定,需要通过notify来唤醒。释放执行权,释放了锁,是一个普通的方法,被设计在了Object类上
线程的基本状态:
线程代码练习:
public class synchronizedDemo { public static void main(String[] args) { syns s = new syns(); synDemo syn = new synDemo(s); synDemo2 syn2 = new synDemo2(s); new Thread(syn).start(); new Thread(syn).start(); new Thread(syn2).start(); new Thread(syn2).start(); //new Thread(syn).start(); } } class synDemo implements Runnable{ private syns s; public synDemo(syns s) { this.s = s; } @Override public void run() { synchronized(s){ // try { // Thread.sleep(3000); // } catch (InterruptedException e) { // e.printStackTrace(); // } // try { // s.wait(); // } catch (InterruptedException e) { // e.printStackTrace(); // } for (int i = 0; i < 3; i++) { String name = Thread.currentThread().getName(); System.out.println(name+":"+i); } //s.notify(); } } } class synDemo2 implements Runnable{ private syns s; public synDemo2(syns s) { this.s = s; } @Override public void run() { synchronized (s) { // try { // Thread.sleep(3000); // } catch (InterruptedException e) { // e.printStackTrace(); // } for (int i = 0; i < 3; i++) { String name = Thread.currentThread().getName(); System.out.println(name+":"+i); } } } } class syns { private int a = 8; }
标签:java线程 类对象 总结 stack 静态 启动方式 pre bsp 业务逻辑
原文地址:http://www.cnblogs.com/tongxuping/p/6832242.html