Java并发编程(1):Java并发编程的基础
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了Java并发编程(1):Java并发编程的基础,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含5200字,纯文字阅读大概需要8分钟。
内容图文
![Java并发编程(1):Java并发编程的基础](/upload/InfoBanner/zyjiaocheng/622/45a1bdc4b3e641008ece2a996925d214.jpg)
Java并发编程基础
一、 多线程初探
先了解两种Java中实现线程的方法:
- 继承Thread类
- 实现Runnable接口
严谨的讲它们是一种方式,都是为了构造Thread类,看Thread类的代码就会发现,Thread类自己是实现了Runnable接口的。
public class Thread implements Runnable
1).继承Thread
public class ThreadDemo extends Thread{
@Override
public void run() {
System.out.println("ThreadDemo");
}
public static void main(String[] args) {
ThreadDemo threadDemo = new ThreadDemo();
threadDemo.start();
}
}
继承Thread类,重写run方法,然后new出这个类的对象,调用start方法,即可启动该线程。
虚拟机并不是在调用start后虚拟机会创建一个线程,但不一定是当时执行run方法,而是需要在该线程分配到时间片的时候才会执行run方法里的代码。
需要注意的是,一个Thread对象不能调用多次start方法,否则会抛出异常。
2).实现Runnable接口
先看一下Runnable接口的源码
@FunctionalInterface
public interface Runnable {
/**
* When an object implementing interface <code>Runnable</code> is used
* to create a thread, starting the thread causes the object's
* <code>run</code> method to be called in that separately executing
* thread.
* <p>
* The general contract of the method <code>run</code> is that it may
* take any action whatsoever.
*
* @see java.lang.Thread#run()
*/
public abstract void run();
}
首先,看注解发现这是一个函数式接口,也就是说Java8之后可以用Lambda的方式来使用这个接口。
下面再看看如何用实现Runnable接口的方式来创建一个线程:
public class ThreadDemo implements Runnable{
@Override
public void run() {
System.out.println("ThreadDemo");
}
public static void main(String[] args) {
new Thread(new ThreadDemo()).start();
}
}
经过Lambda简化之后的方式:
public class ThreadDemo {
public static void main(String[] args) {
new Thread(() -> {
System.out.println("Lambda ThreadDemo");
}).start();
}
}
即可以不写一个具体类来实现,而是直接用Lambda表达式表示。
2.Thread类介绍
想要熟悉一个类最好的方式是使用它的API和阅读它的源码,我们已经知道了如何构造Thread类来开启一个线程,下面就详细介绍一下Thread类的方法。
1) Thread的构造方法
/**
* Allocates a new {@code Thread} object. This constructor has the same
* effect as {@linkplain #Thread(ThreadGroup,Runnable,String) Thread}
* {@code (null, null, gname)}, where {@code gname} is a newly generated
* name. Automatically generated names are of the form
* {@code "Thread-"+}<i>n</i>, where <i>n</i> is an integer.
*/
public Thread() {
init(null, null, "Thread-" + nextThreadNum(), 0);
}
/**
* Allocates a new {@code Thread} object. This constructor has the same
* effect as {@linkplain #Thread(ThreadGroup,Runnable,String) Thread}
* {@code (null, target, gname)}, where {@code gname} is a newly generated
* name. Automatically generated names are of the form
* {@code "Thread-"+}<i>n</i>, where <i>n</i> is an integer.
*
* @param target
* the object whose {@code run} method is invoked when this thread
* is started. If {@code null}, this classes {@code run} method does
* nothing.
*/
public Thread(Runnable target) {
init(null, target, "Thread-" + nextThreadNum(), 0);
}
Thread类有9个构造方法,写下的两个是我们刚使用过的,可以看到Thread类的构造方法都是通过init构造的。下面看看init方法:
/**
* Initializes a Thread with the current AccessControlContext.
* @see #init(ThreadGroup,Runnable,String,long,AccessControlContext,boolean)
*/
private void init(ThreadGroup g, Runnable target, String name,
long stackSize) {
init(g, target, name, stackSize, null, true);
}
/**
* Initializes a Thread.
*
* @param g the Thread group
* @param target the object whose run() method gets called
* @param name the name of the new Thread
* @param stackSize the desired stack size for the new thread, or
* zero to indicate that this parameter is to be ignored.
* @param acc the AccessControlContext to inherit, or
* AccessController.getContext() if null
* @param inheritThreadLocals if {@code true}, inherit initial values for
* inheritable thread-locals from the constructing thread
*/
private void init(ThreadGroup g, Runnable target, String name,
long stackSize, AccessControlContext acc,
boolean inheritThreadLocals)
init方法的5个参数分别是
- ThreadGroup g 这个参数顾名思义,表示线程组,用于指定这个线程是在哪个线程组里。
- Runnable target 这个参数上面使用过,传入Runnable定义的run方法,用于定义线程需要执行的任务。
- String name 用于定义线程的名称
- long stackSize 用于定义新线程栈空间的大小,或者传入0则这个值将被忽略。
- AccessControlContext acc 查看代码发现acc只在调用Thread的init方法时被赋值给
inheritedAccessControlContext
这个私有成员变量,而这个私有成员变量也只在Thread的exit()方法中被赋值为null。对于用户来说也只有如下构造方法能给这个成员赋值:
/**
* Creates a new Thread that inherits the given AccessControlContext.
* This is not a public constructor.
*/
Thread(Runnable target, AccessControlContext acc) {
init(null, target, "Thread-" + nextThreadNum(), 0, acc);
}
AccessControlContext用于制定系统资源访问决策基于它封装的上下文。
更具体的说,它封装了一个上下文和一个单独的方法 checkPermission,这个方法和 AccessController 里的checkPermission方法是相同的,只有一个区别就是AccessControlContext的checkPermission基于它封装的上下文作出决策,而不是基于当前执行的线程。
因此AccessControlContext的用途是给那些需要给定上下文的安全检查的情形,实际上是给定的不同的上下文,例如从辅助线程中。
6. boolean inheritThreadLocals 是可继承的ThreadLocal
也就是线程组,后面会深入介绍线程组的概念。
内容总结
以上是互联网集市为您收集整理的Java并发编程(1):Java并发编程的基础全部内容,希望文章能够帮你解决Java并发编程(1):Java并发编程的基础所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。