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. EasyUI Tree 动态传递参数

    1.问题背景 一般出现在加载的时候,传递参数给后台,进行数据筛选,然后在加载tree渲染数据.所谓动态参数,可以是你的上一级节点node,或者是根节点node. 2.涉及方法 onBeforeLoad ...

  2. leetcode 题解:Merge Sorted Array(两个已排序数组归并)

    题目: Given two sorted integer arrays A and B, merge B into A as one sorted array. Note:You may assume ...

  3. 《JAVA核心卷I》之Java基本程序结构

    Java基本程序结构 1.类名是以大写字母开头的名词代码能够执行的类,要有main函数,且声明必须是public 2.注释:  “//”,"/**/" 行注释  "/** ...

  4. 转:提高ios通过率的注意点

    http://bugly.qq.com/bbs/forum.php?mod=viewthread&tid=431 Bugly 技术干货系列内容主要涉及移动开发方向,是由 Bugly 邀请腾讯内 ...

  5. EffectiveJava(17)要么为继承而设计,要么禁止继承

    1.如果为了继承而设计类,那么该类必须有文档说明它可覆盖的方法的自用性.对于每个公有的 或受保护的方法或者构造器,它的文档必须指明该方法或者构造器调用了那些可覆盖的方法,是以 什么顺序调用的,每个调用 ...

  6. Web 目录枚举与遍历漏洞解决

    "目录枚举漏洞"解决方法 一.名词解释 网站目录枚举漏洞:指黑客利用非法攻击手段扫描符合"8.3"命名原则的目录与文件. 二.验证工具:scanner-comp ...

  7. Win7系统管理员设置了系统策略,禁止进行此安装,怎么办

    系统管理员设置了系统策略,禁止进行此安装,怎么办 最佳答案 尝试方法一:   windows开始菜单,运行里面输入gpedit.msc打开组策略,   在"计算机配置"→管理模板→ ...

  8. C++003基础

    1.C++对C的扩展 1简单的C++程序 1.1求圆的周长和面积 数据描写叙述: 半径.周长,面积均用实型数表示 数据处理: 输入半径 r. 计算周长 = 2*π*r : 计算面积 = π* r2 . ...

  9. synchronized的功能拓展:重入锁(读书笔记)

     重入锁可以完全代替synchronized关键字.在JDK5.0的早期版本中,重入锁的性能远远好于synchronized,但是从JDK6.0开始.JDK在synchronized上做了大量的优化. ...

  10. Java---24---基本数据类型对象包装类

    基本数据类型对象包装类 byte Byte short  short int  Integer boolean  Boolean float    Float double   Double char ...