1.线程及启动和终止

1.1 线程 -进程/优先级

操作系统调度的最小单元是线程,线程是轻量级进程。

线程优先级由setPriority(int)方法来设置,默认优先级是5,等级1~10.等级越高分的时间片越多。

1.2 线程的状态

new 初始化 》》Runable 运行》》Blocked阻塞 》》Wating等待》》 time_Wating超时等待》》 temerinated终止状态。

1.3 Daemon辅助线程

主线程终止后,辅助线程也就结束。thread.setDaemon(true)设置在线程开始之前。

1.4 过期suspend() , resume(), stop()为啥不建议使用?

suspend()调用后太霸道,不释放占有资源,而是抱着占有资源去睡觉,这样容易死锁。站着茅坑不拉屎。

resume()、stop()不保证线程资源正常释放,那要你们何用?

安全的终止线程:有中断操作,和自定义cancel()方法。

 package Thread;

 import java.util.concurrent.TimeUnit;

 /**
* Created by Sky on 2016/9/22.
* @author xiaoyongyong
*/
public class Shutdown {
public static void main(String[] args) throws InterruptedException {
Runner one = new Runner();
Thread countThread = new Thread(one,"CountThread");
countThread.start();
TimeUnit.SECONDS.sleep(1);
countThread.interrupt(); Runner two = new Runner();
countThread = new Thread(two,"CountThread");
countThread.start();
TimeUnit.SECONDS.sleep(1);
two.cancle();
} private static class Runner implements Runnable{
private long i;
private volatile boolean on =true;
@Override
public void run() {
while (on && !Thread.currentThread().isInterrupted()){
i++;
}
System.out.println("Count i ="+ i);
}
public void cancle(){
on = false;
}
}
}

2. 线程之间通信

2.1 volatile 和 synchronized 关键字。

volatile:它能保证所有线程对变量访问的可见性,即某线程对定义变量的修改,其他线程可见。谨慎使用,过多使用会降低程序运行效率。

syncchronized:保证只有一个线程能对其定义的变量修改。保证其变量访问的可见性和排他性。

2.2 通知/等待机制

可以确保及时性和降低开销。

相关方法:notify()、nitifyAll()、wait()、wait(long)、wait(long,int)。

注意点:1)使用notify()、nitifyAll()、wait()时需要先对调用对象加锁。2)notify()、nitifyAll()方法调用后,等待线程依旧不会从wait()方法返回,

需要调用notify()、nitifyAll()方法的线程,释放锁之后,等待线程才有机会从wait()返回。等待队列-》同步队列。3)wait()方法返回的前提是获取对象锁。

这种机制可以运用在生产者-消费者模式中。

 package Thread;

 import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.TimeUnit; /**
* Created by Sky on 2016/9/22.
*
* @author xiaoyongyong
*/
public class WaitNotify {
static boolean flag = true;
static final Object lock = new Object(); public static void main(String[] args) throws Exception {
Thread waitTread = new Thread(new Wait(), "WaitTread");
waitTread.start();
TimeUnit.SECONDS.sleep(1); Thread notifyTread = new Thread(new NotifyTread(), "NotifyTread");
notifyTread.start();
} private static class Wait implements Runnable {
@Override
public void run() {
synchronized (lock) {
while (flag) {
try {
System.out.println(Thread.currentThread() + " flag is true.wait. " + new SimpleDateFormat("HH:mm:ss").format(new Date()));
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(Thread.currentThread() + " flag is true.running. " + new SimpleDateFormat("HH:mm:ss").format(new Date()));
}
}
} private static class NotifyTread implements Runnable {
@Override
public void run() {
synchronized (lock){
System.out.println(Thread.currentThread() + " hold lock.notify. " + new SimpleDateFormat("HH:mm:ss").format(new Date()));
lock.notifyAll();
flag = false;
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
synchronized (lock) {
System.out.println(Thread.currentThread() + " hold lock.again.sleep " + new SimpleDateFormat("HH:mm:ss").format(new Date()));
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}

返回结果:

Thread[WaitTread,5,main] flag is true.wait. 22:03:45
Thread[NotifyTread,5,main] hold lock.notify. 22:03:46
Thread[NotifyTread,5,main] hold lock.again.sleep 22:03:48
Thread[WaitTread,5,main] flag is true.running. 22:03:50

2.3 管道输入/输出流

主要用于线程之间的数据传输,传输媒介是内存,有PipedOutputStream/PipedInputStream(面向字节)  和PipedReader/PipedWriter(面向字符)。

 package Thread;

 import java.io.IOException;
import java.io.PipedReader;
import java.io.PipedWriter; /**
* Created by Sky on 2016/9/22.
* @author xiaoyongyong
*/
public class Piped {
public static void main(String[] args) throws IOException {
PipedWriter out = new PipedWriter();
PipedReader in = new PipedReader();
out.connect(in);
Thread printThread = new Thread(new Print(in), "PringThread");
printThread.start(); int receive;
try {
while ((receive = System.in.read()) != -1) {
out.write(receive);
}
} finally {
out.close();
}
} private static class Print implements Runnable {
private PipedReader in;
public Print(PipedReader in) {
this.in = in;
}
@Override
public void run() {
int receive;
try {
while ((receive = in.read()) != -1) {
System.out.print((char) receive);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

输入一串字符串,按enter后,将原样输出。管道输入输出流必须先连接才可复制,即connect()。

2.4 Thread.join()的使用

当线程A等待thread线程终止之后,才从thread.join()返回。

join方法顾名思义 就是往线程中添加东西的;join方法可以用于临时加入线程,一个线程在运算过程中,如果满足于条件,我们可以临时加入一个线程,让这个线程运算完,另外一个线程再继续运行。

Thread,yeld()和Thread.sleep()的区别?

hread.yield()方法暂停当前正在执行的线程对象,并执行其他线程。也就是交出CPU一段时间(其他同样的优先级或者更高优先级的线程可以获取到运行的机会);不会释放锁资源。

而Thread.sleep()方法使当前线程进入停滞状态,所以执行sleep()的线程在指定的时间内肯定不会执行, 同时sleep函数不会释放锁资源;sleep可使优先级低的线程得到执行的机会,当然也可以让同优先级和高优先级的线程有执行的机会。

这两个的区别在于yield只能是同级,或者高级优先执行,而sleep可以低级,同级都可以有优先执行机会。

2.5 ThreadLocal的使用

线程变量,是一个以TreadLocal对象为键,任意对象为值得存储结构。

2.6 线程池技术及示例。

以下是线程池接口的定义和实现:

package Thread;

/**
* Created by asus on 2016/9/27.
*/
public interface ThreadPool<Job extends Runnable> {
void execute(Job job);
void shutdown();
void addWorkers(int num);
void removeWoker(int num);
int getJobSize();
}
package Thread;

import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.atomic.AtomicLong; /**
* Created by asus on 2016/9/27.
*
* @author xiaoyongyong
*/
public class DefaultThreadPool<Job extends Runnable> implements ThreadPool<Job> {
private static final int MAX_WORKER_NUMBERS = 10;
private static final int DEFAULT_WORKER_NUMBERS = 5;
private static final int MIN_WORKER_NUBERS = 1;
private final LinkedList<Job> jobs = new LinkedList<Job>();
private final List<Worker> workers = Collections.synchronizedList(new ArrayList<Worker>());
private int workerNum = DEFAULT_WORKER_NUMBERS;
private AtomicLong threadNum = new AtomicLong(); public DefaultThreadPool() {
initializeWorker(DEFAULT_WORKER_NUMBERS);
} private void DefaultThreadPool(int num) {
workerNum = num > MAX_WORKER_NUMBERS ? MAX_WORKER_NUMBERS : num < MIN_WORKER_NUBERS ? MAX_WORKER_NUMBERS : num;
initializeWorker(workerNum);
} @Override
public void execute(Job job) {
if (job != null) {
synchronized (jobs) {
jobs.add(job);
jobs.notify();
}
}
} @Override
public void shutdown() {
for (Worker worker : workers) {
worker.shutdown();
}
} @Override
public void addWorkers(int num) {
synchronized (jobs) {
if (num + this.workerNum > MAX_WORKER_NUMBERS) {
initializeWorker(num);
this.workerNum += num;
}
}
} @Override
public void removeWoker(int num) {
synchronized (jobs) {
if (num >= this.workerNum) {
throw new IllegalArgumentException("beyond workerNum");
}
int count = 0;
while (count < num) {
Worker worker = workers.get(count);
if (workers.remove(worker)) {
worker.shutdown();
count++;
}
}
this.workerNum -= count;
}
} @Override
public int getJobSize() {
return jobs.size();
} private void initializeWorker(int num) {
for (int i = 0; i < num; i++) {
Worker worker = new Worker();
workers.add(worker);
Thread threadWorker = new Thread(worker, "ThreadPool-Worker-" + threadNum.incrementAndGet());
threadWorker.start();
}
} class Worker implements Runnable {
private volatile boolean running = true; @Override
public void run() {
while (running){
Job job = null;
synchronized (jobs){
while (jobs.isEmpty()){
try {
jobs.wait();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
e.printStackTrace();
return;
}
}
job = jobs.removeFirst();
}
if(job != null){
job.run();
}
}
} public void shutdown() {
running = false;
}
}
}

2.7 基于县此次技术的简单Web服务器

这个服务器使用main线程不断接受客户端Socket的连接,将连接以及请求交给线程池处理,这样使得Web服务器能够同同时处理多个客户端请求。

java并发编程基础---Sky的更多相关文章

  1. Java并发编程基础

    Java并发编程基础 1. 并发 1.1. 什么是并发? 并发是一种能并行运行多个程序或并行运行一个程序中多个部分的能力.如果程序中一个耗时的任务能以异步或并行的方式运行,那么整个程序的吞吐量和可交互 ...

  2. 并发-Java并发编程基础

    Java并发编程基础 并发 在计算机科学中,并发是指将一个程序,算法划分为若干个逻辑组成部分,这些部分可以以任何顺序进行执行,但与最终顺序执行的结果一致.并发可以在多核操作系统上显著的提高程序运行速度 ...

  3. Java并发编程--基础进阶高级(完结)

    Java并发编程--基础进阶高级完整笔记. 这都不知道是第几次刷狂神的JUC并发编程了,从第一次的迷茫到现在比较清晰,算是个大进步了,之前JUC笔记不见了,重新做一套笔记. 参考链接:https:// ...

  4. Java并发编程基础-线程安全问题及JMM(volatile)

    什么情况下应该使用多线程 : 线程出现的目的是什么?解决进程中多任务的实时性问题?其实简单来说,也就是解决“阻塞”的问题,阻塞的意思就是程序运行到某个函数或过程后等待某些事件发生而暂时停止 CPU 占 ...

  5. java并发编程基础概念

    本次内容主要讲进程和线程.CPU核心数和线程数.CPU时间片轮转机制.上下文切换,并行和并发的基本概念以及并发编程的好处和注意事项,为java并发编程打下扎实基础. 1.什么是进程和线程 1.1 进程 ...

  6. 多线程(一)java并发编程基础知识

    线程的应用 如何应用多线程 在 Java 中,有多种方式来实现多线程.继承 Thread 类.实现 Runnable 接口.使用 ExecutorService.Callable.Future 实现带 ...

  7. Java并发编程基础三板斧之Semaphore

    引言 最近可以进行个税申报了,还没有申报的同学可以赶紧去试试哦.不过我反正是从上午到下午一直都没有成功的进行申报,一进行申报 就返回"当前访问人数过多,请稍后再试".为什么有些人就 ...

  8. Java并发编程基础之volatile

    首先简单介绍一下volatile的应用,volatile作为Java多线程中轻量级的同步措施,保证了多线程环境中“共享变量”的可见性.这里的可见性简单而言可以理解为当一个线程修改了一个共享变量的时候, ...

  9. java并发编程基础——线程的创建

    一.基础概念 1.进程和线程 进程:每个进程都有独立的代码和数据空间(进程上下文),进程间的切换会有较大的开销,一个进程包含1--n个线程.(进程是资源分配的最小单位) 线程:同一类线程共享代码和数据 ...

随机推荐

  1. EffectiveJava(11)Java中的clone

    java中的clone clone构造器及其静态工厂的变形 优点:它们不依赖于某一种很有风险的,语言之外的对象创建机制; 它们不要求遵守尚未制定好文档的规范 他们不会于final域的正常使用发生冲突 ...

  2. 倍福TwinCAT(贝福Beckhoff)基础教程6.1 TwinCAT如何与高级语言通讯

    因为使用TwinCAT的人用途不同,重视点就不同.如果用来代替传统PLC+HMI做项目的,很少会需要用到跟高级语言通讯,但是如果是用来做运动控制平台如做机器人运动控制器的,就肯定会用到.不管是否用得上 ...

  3. PS如何使用自定义画笔

    1 没有杂色的白背景不用抠图,GIF格式的透明背景不用抠图,有背景但是不想抠图都可以直接定义为画笔.先选中需要定义的画笔(得到选区),然后单击编辑-定义画笔预设.   2 随后就可以找到我们的画笔工具 ...

  4. linux命令之------vmstat使用

    在linux命令中,vmstat是个经常用到的分析系统性能的命令之一,主要有两个参数:一个是采样频率,一个是采样的次数.如:vmstat   1  3,意思就是每隔1秒采样1次,总共采样3次. 统计次 ...

  5. node - post - 上传图片

    html代码: <!DOCTYPE html> <html lang="en"> <head> <meta charset="U ...

  6. close_wait状态的产生原因及解决(转)

    最近测试环境server由于需要与大量的后台server交互,今天突然发现有大量的close_wait产生,于是仔细研究了一下: 如果我们的服务器程序处于CLOSE_WAIT状态的话,说明套接字是被动 ...

  7. xml中处理特殊字符和转义字符

    XML 中的特殊字符 > 和 开始标记 > 例如: 5 ]] 如何获得这些HTML内容呢? XmlDocument doc = new XmlDocument(); doc.Load(&q ...

  8. 中小企业 DevOps 从 0 到 1

    原文:http://www.sohu.com/a/145065274_262549 今天主要有四个课题: 先聊一聊 DevOps: 然后跟大家聊一聊运维知识的体系和职业发展: 再是中小企业基于开源的 ...

  9. Linux Suse 查看wwn号码的方法

     查看wwn号码 cat /sys/class/fc_host/host*/port_name *代表全部host目录

  10. 简洁方便的集合处理——Java 8 stream流

    背景 java 8已经发行好几年了,前段时间java 12也已经问世,但平时的工作中,很多项目的环境还停留在java1.7中.而且java8的很多新特性都是革命性的,比如各种集合的优化.lambda表 ...