java线程,了解一下

运行一个应用程序,至少有一个进程产生

一个进程中可能有多个线程

线程是程序执行流的最小单元

是程序中一个单一的顺序控制流程

进程内一个相对独立的、可调度的执行单元

是系统独立调度和分派CPU的基本单位指运行中的程序的调度单位

在单个程序中同时运行多个线程完成不同的工作,称为多线程

Java vm 运行的时候会有一个进程java.exe

该进程至少有一个线程负责java程序的执行

这个线程的运行的代码存在于main方法中

该线程称之为主线程

扫描二维码关注公众号,回复: 2956712 查看本文章

线程的五种状态

new Thread

runnable 就绪
线程启动,等待分配CPU时间片
通过调用线程实例的start 方法来启动线程进入就绪状态
还没有分配到cpu,不一定会立即执行,处于就绪队列
线程的状态是alive

running 运行
获得cpu资源正在执行run 方法
线程状态是alive

blocked 阻塞
某种原因导致正在运行的线程让出cpu暂停自己的执行
sleep
wait,可以使用notify方法回到就绪状态
被另一个线程所阻塞,调用suspend。可调用resume方法恢复
线程状态alive

dead
线程终止
自然终止
异常终止
执行完毕或被kill
不可能进入就绪状态
线程状态 not alive

线程的创建

每一个线程都是一个对象

它的类实现Runnable接口或者扩展实现了Runnable接口的类

这种新的对象成为可运行对象

进程拥有时间段,每次执行一个进程//详细参考《操作系统》

要创建并运行一个线程
先定义Thread的一个子类
必须覆盖run()方法
该方法告诉系统如何执行线程
然后在线程上创建一个运行对象
调用线程的start方法 启动线程

线程启动

x.start();// 执行线程 start 调用的是run方法的内容
x.run();//start 也是执行的这个run方法 线程创建并没有运行

线程方法

currentThread.sleep(111);  
            /*
             * 释放cpu执行权,不释放锁
             * 睡眠时间为最小不执行时间,睡眠时间到后,不一定立即被唤醒
             * 不会停止其他线程也处于休眠状态
             * 睡眠状态不会失去拥有的对象锁
             * 
             * 保持对象锁,让出cpu,不让当前线程独霸cpu
             */


            currentThread.wait();
            /*
             * 释放cpu执行权,释放锁
             * 进入到一个和该对象相关的等待池
             * 暂时失去了对象的锁机制
             * 之后还会返回对象锁
             * 
             * 当前线程必须拥有当前对象的锁
             * 不然会抛出 IllegalMonitorStateException异常
             * 
             * 所以wait必须在synchronized block 中调用
             */



            currentThread.notify();
            currentThread.notifyAll();
            /*
             * 唤醒在当前对象等待池中的线程/all
             *  必须拥有相同的对象锁,否则抛出异常
             */

            currentThread.yield();
            /*
             * 临时暂停当前线程,让出cpu使用权
             * 如果没有同等优先权的线程,就不会起作用
             */
        Thread currentThread = Thread.currentThread();
        System.out.println("currentThreadName =" + currentThread.getName());
        System.out.println("id =" + currentThread.getId() );
        System.out.println("state = "+ currentThread.getState());
        System.out.println("group = " + currentThread.getThreadGroup());
        System.out.println("Alive =" + currentThread.isAlive());
        System.out.println("daemon = " + currentThread.isDaemon());
        System.out.println("count = " + currentThread.activeCount());

线程创建方式一继承Thread


public class T1 extends Thread   {
    @Override
    public void run() {
        super.run();
        System.out.println("t1.run "   );
    }



    public static void main(String[] args) {
         T1 t1 = new T1();
          t1.start();
          System.out.println(t1.getName());
          System.out.println(t1.getId());
    }

}

线程创建方式二 实现runable接口

//1实现runable接口2覆盖run方法3通过Thread类建立线程对象
//4将runable接口的子类对象作为实际参数传给Thread类的构造函数
//run方法所属的对象时runable接口的子类对象
//调用Thread中的start方法开启线程并调用runable接口子类的run方法
// synchronized   可以修饰函数  此函数可以同步
public class T2 implements Runnable {

    @Override
    public void run() {
        System.out.println( "run :"+"t2.run...");

        try {
            Thread.sleep(10L);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        T2 t2 = new T2();

            new Thread(t2,"name is " + "hello").start();


    }
}

线程创建方式三


import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

public class T3 implements Callable<String>{

    @Override
    public String call() throws Exception {
        return "t3.call..";
    }

    public static void main(String[] args) {
        T3 t3 = new T3();
        FutureTask<String> futureTask = new FutureTask<>(t3);

        new Thread(futureTask).start();

        try { 
            System.out.println(futureTask.get());
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }

}

线程死锁

2016年12月2日

 class Bank extends Thread{
    static   int i = 5000;
        public Bank(String name) {
            super(name);
        }
        @Override
//          同步函数
//      同步函数的锁对象
        /*
         * 如果是一个非静态的同步函数锁,对象是this对象
         * 如果是一个静态的同步函数锁,对象是当前函数所属的类的字节码文件(class对象)
         * 同步函数的锁对象是固定的,不能指定
         */
        //同步代码解决了线程安全
        /*
         * 同步代码块的锁对象可以由我们随意指定,方便控制,同步函数的锁对象是固定的,不能由我们来指定(非 Javadoc)
         * 同步代码块可以很方便控制需要被同步代码的范围,同步函数必须是整个函数的所有代码都被同步了
         */
        //死锁现象
        /*
         * (非 Javadoc)
         * @see java.lang.Thread#run()
         */

        public synchronized void run() {  
            while(true)
            {   //对象必须是内存中唯一的,不然就锁不住
                synchronized ( "suo") {
                    if (i > 0) {
                        System.out.println(Thread.currentThread().getName() + " 取走一千 " + (i-1000));
                        i = i - 1000;
                    } else {
                        System.out.println("没钱");
                        break;
                    }
                }
            }
        }
    }

线程中断

        currentThread.stop();  
        //不建议使用 


        /**
         * java中断机制是一种协作机制
         * 通过中断不能直接终止另一个线程,而需要线程自己处理中断
         * 
         */

        currentThread.interrupted();
//      测试当前线程是否中断
//      线程中断的状态由该方法清除
//      连续调用两次,返回false

        currentThread.isInterrupted();
//      测试线程是否已经中断


        currentThread.interrupt();
//      中断线程

守护线程

currentThread.setDaemon(true);
            /*
             * 设置线程为守护线程
             * 该线程推出时会先调用该线程的checkAccess方法,不带任何参数
             * 
             * jvm的垃圾回收、内存管理等都是守护线程
             *      
             */

线程异常

run方法不允许throw exception ,所有的异常必须在run 方法内进行处理

线程是独立执行的代码片段
线程的问题应该有线程自己来解决
不要委托到外部

checked exception 使用 try/catch

unchecked exception 是注册一个UncaughtExceptionHandler接口的对象实例来处理

 static class MyThreadException implements UncaughtExceptionHandler{

        @Override
        public void uncaughtException(Thread t, Throwable e) {
            System.out.println(t.getName()+t.getId() + t.getClass().getName());
        }

     }



currentThread.setUncaughtExceptionHandler(new MyThreadException());

猜你喜欢

转载自blog.csdn.net/java_sparrow/article/details/81214514