流年似水博客开通了,本站主要是写关于Web和大数据方面内容,正在更新中,欢迎大家光临!
  1. 文章:97 篇
  2. 总浏览:33,708 次
  3. 评论:22条
  4. 最后更新:2020-06-08
  5. 分类目录:39 个

Java之线程详解

Java l, xy 158℃ 0评论
  1.   线程概述

(1)      线程(英语:thread)是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。在Unix System VSunOS中也被称为轻量进程(lightweight processes),但轻量进程更多指内核线程(kernel thread),而把用户线程(user thread)称为线程。

  1.   线程的好处

(1)      有效的利用的CUP的空闲时间,提高了CUP的利用率

(2)      可以提高用户体验

  1.   创建线程的方式

(1)      继承Thread类型

(2)      实现Runnable接口

(3)      实现Callable接口

(4)      线程池

  1.   线程的停止

(1)      Thread中有结束线程的方法(stop()已经过时)

(2)      自己编程的方式实现(通知法)

  1.   线程(Thread)的常用方法

(1)      构造方法

1           public Thread()

2           public Thread(Runnable target)

3           public Thread(ThreadGroup group,Runnable target)

4           public Thread(String name)

5           public Thread(ThreadGroup group,String name)

6           public Thread(Runnable target,String name)

7           public Thread(ThreadGroup group,Runnable target,String name)

8           public Thread(ThreadGroup group,Runnable target,String name,long stackSize)

(2)      静态方法

1           public static native Thread currentThead()

2           public static native void yield()

3           public static native void sleep(long mills)

4           public static native void sleep(long mills,int nanos)

5           public static boolean interrupted()

6           public static int activeCount()

7           public static int enumerate(Thread[] tarry)

8           public static synchronized void join(long millis)

9           public static synchronized void join(long millis,int nanos)

10       public static synchronized void join()

11       public static void dumpStack() 使用标准错误流打印当前线程的堆信息,只用于调试

12       publci static native boolean holdsLock(Object obj) 判断当前线程是否持有指定对象obj锁,持有返回true,否则返回false

13       public static Map<Thread,StackTrackElement[]> getAllStackTraces()

14       public static void setDefaultUncaughtException(UncaughtExceptionHandler eh)

15       public static UncaughtExceptionHandler getDefaultUncaughtExceptionHandler()

(3)      常用方法

1           public void run()

2           public void start()

3           public void interrupt()

4           public boolean interrupted()

5           public boolean isInterruted()

6           public final native boolean isAlive()

7           public final void setPriority(int newPriority)

8           public final int getPriority()

9           public final synchronized void setName(String name)

10       public final String getName()

11       public final ThreadGroup getThreadGroup()

12       public final void setDaemon(boolean on)

13       public final boolean isDeamon()

14       public final void checkAccess()

15       public ClassLoader getContextClassLoader()

16       public void setContextClassLoader(ClassLoader cl)

17       public StackTraceElement[] getStackTrace()

18       public long getId()

19       public State getState()

20       public UncaughtExceptionHandler getUncaughtExceptionHandler()

21       public void setUncaughtExceptionHandler(UncaughtExceptionHandler eh)

 

  1.   线程的声明周期

  1.   线程的同步

(1)      使用前提:

1           多线程

2           多个线程共同访问共享资源

(2)      解决方法:

1           一个线程访问共享资源时,其他线程不能参与进来(不能进来),上锁。

 

(3)      同步方法

1           成员方法

1)         定义:

public synchronized void two(){
    //同步代码
}

 

2)         线程锁对象:线程锁对象this,即当前对象

2           类方法

1)         定义:

public static synchronized void one() {
   //同步代码
}

 

2)         线程锁对象:线程锁对象为类的class对象,即类Class对象

3           注意:

1)         方法定义时,synchronized的关键字要放在方法返回值的前面

 

(4)      同步代码块

1           定义格式

synchronized(锁对象){

//同步代码

}

2           注意事项

1)         使用同步代码块时,锁对象可以是任意对象

 

(5)      释放锁的情况总结

1           同步代码块或者同步方法正常指定结束

2           同步代码块或者同步方法发生异常时且没有处理,直接抛出。

3           同步代码块或者同步方法遇到return

4           同步代码块如果使用循环、switch分支包裹着是,遇到break时。

(6)      不会释放锁情况总结

1           调用sleep()方法不会释放锁

2           调用yield()方法也不会释放锁

 

(7)      注意事项:

1           在使用同步代码块或者同步方法时,一定要找到合适的锁对象,如果多个线程使用的不是一个锁对象,虽然语法不报错,但是任然达不到同步的目的

  1.   线程的死锁

(1)      死锁:当两个或者两个以上线程运行需要两个或者两个以上的锁对象时,其中一个线程持有一个对象锁,另外一个线程只有另外一个对象锁。此时两个线程都不肯放弃自己所持有的锁,都想要对方持有的锁。这种僵持局面,称为死锁。

(2)      原因:

1           两个或者对个线程分别持有对方线程锁运行锁需要的锁,而都不放弃(多个线程都占有了对方的锁资源,都不相让,就导致了死锁)

(3)      案例代码:

/**
* 演示死锁
*/
public class DeadLockDemo {
    public static void main(String[] args) {
        new Thread1(true).start();
        new Thread1(false).start();
    }
}
class Thread1 extends Thread {
    private boolean flag;
    private static Object lock1 = new Object();
    private static Object lock2 = new Object();
    public Thread1(boolean flag) {
        this.flag = flag;
    }
    @Override
    public void run() {
        if (flag) {
            synchronized (lock1) {
                System.out.println(Thread.currentThread().getName() + "--进入了lock1");
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized (lock2) {
                    System.out.println(Thread.currentThread().getName() + "--进入了lock2");
                }
            }
        } else {
            synchronized (lock2) {
                System.out.println(Thread.currentThread().getName() + "**进入了lock2");
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized (lock1) {
                    System.out.println(Thread.currentThread().getName() + "**进入了lock1");
                }
            }
        }
    }
}

 

(4)      死锁的解决:

1           解决方案:在最外层添加一个公共的锁,将发生死锁的代码包裹起来。

package cn.cupcat.day23.thread;
/**
* 演示死锁的解决方案
*/
public class DeadLockDemo {
    public static void main(String[] args) {
        new Thread1(true).start();
        new Thread1(false).start();
    }
}
class Thread1 extends Thread {
    private boolean flag;
    private static Object lock1 = new Object();
    private static Object lock2 = new Object();
    //添加一把公共的锁
    private static Class publicLock = Thread1.class;
    public Thread1(boolean flag) {
        this.flag = flag;
    }
    @Override
    public void run() {
        if (flag) {
            synchronized (publicLock) {
                synchronized (lock1) {
                    System.out.println(Thread.currentThread().getName() + "--进入了lock1");
                    try {
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    synchronized (lock2) {
                        System.out.println(Thread.currentThread().getName() + "--进入了lock2");
                    }
                }
            }
        } else {
            synchronized (publicLock) {
                synchronized (lock2) {
                    System.out.println(Thread.currentThread().getName() + "**进入了lock2");
                    try {
                        Thread.sleep(3000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    synchronized (lock1) {
                        System.out.println(Thread.currentThread().getName() + "**进入了lock1");
                    }
                }
            }
        }
    }
}

 

2           解决方案二:让其中一个线程放弃锁,另外一个线程运行。

  1.   线程间通信

(1)      线程通信:多线程之间能够互相的通信

(2)      前提:

1           必须在同步的基础上

2           要求waitnotifynotifyAll的调用者必须是同一对象

(3)      步骤:

1           必须添加上同步

2           分析waitnotity或者notifyAll方法的位置

3           检测waitnoitfynotify的调用者是否是同一把锁

(4)      通信方法:使用锁对象调用

1           wait(): 当前线程等待(放弃锁),需要其他线程唤醒(notify(),notifyAll)或者中断(interrupt()

2           notify() :唤醒线程

3           notifyALl():唤醒所有wait的线程

 

转载请注明:流年似水 » Java之线程详解

喜欢 (0)or分享 (0)

Warning: copy(https://cn.gravatar.com/avatar/?s=54&d=%2Fwp-content%2Fthemes%2Fyusi1.0%2Fimg%2Fdefault.png&r=g): failed to open stream: HTTP request failed! HTTP/1.1 400 Bad Request in /usr/share/nginx/html/timewentby/wp-content/themes/yusi1.0/functions.php on line 239

Warning: copy(/wp-content/themes/yusi1.0/img/default.png): failed to open stream: No such file or directory in /usr/share/nginx/html/timewentby/wp-content/themes/yusi1.0/functions.php on line 243
发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址