1、多线程概述
    1)进程:
        正在运行的程序,是系统进行资源分配和调用的独立单位。
        每一个进程都有它自己的内存空间和系统资源。
    2)线程:
        在同一个进程内又可以执行多个任务,而这每一个任务我就可以看出是一个线程。
    线程:是程序的执行单元,执行路径。是程序使用CPU的最基本单位。
    单线程:程序只有一条执行路径。
    多线程:程序有多条执行路径。    
    3)多线程有什么意义?
    多线程的存在,不是提高程序的执行速度。其实是为了提高应用程序的使用率。
    程序的执行其实都是在抢CPU的资源,CPU的执行权。多个进程是在抢这个资源,而其中的某一个进程如果执行路径比较多,就会有更高的几率抢到CPU的执行权。我们是不敢保证哪一个线程能够在哪个时刻抢到,所以线程的执行有随机性。
    4)并行和并发
        并发是逻辑上同时发生,指在某一个时间内同时运行多个程序。
        并行是物理上同时发生,指在某一个时间点同时运行多个程序。
    5)Java程序运行原理
        java 命令会启动 java 虚拟机,启动 JVM,等于启动了一个应用程序,也就是启动了一个进程。该进程会自动启动一个 “主线程” ,然后主线程去调用某个类的 main 方法。所以 main方法运行在主线程中。在此之前的所有程序都是单线程的。
        jvm虚拟机的启动是多线程的。因为垃圾回收线程也要先启动,否则很容易会出现内存溢出。现在的垃圾回收线程加上前面的主线程,最少启动了两个线程,所以,jvm的启动是多线程的。
 
2、多线程实现方案
  1) Java可以去调用C/C++写好的程序来实现多线程程序。由C/C++去调用系统功能创建进程,然后由Java去调用这样的东西,然后提供一些类供我们使用。我们就可以实现多线程程序了。
  2)实现方式1:继承Thread类。将类声明为 Thread 的子类。该子类应重写 Thread 类的 run 方法。接下来可以分配并启动该子类的实例。
            A:自定义类MyThread继承Thread类。
            B:MyThread类里面重写run()
            C:创建对象
            D:启动线程
例子1:
自定义线程类:

package threaddemos;
/*
* 该类要重写run()方法,为什么呢?
* 不是类中的所有代码都需要被线程执行的。
* 而这个时候,为了区分哪些代码能够被线程执行,java提供了Thread类中的run()用来包含那些被线程执行的代码。
*/
public class MyThread extends Thread{
@Override
public void run(){
for (int x = 0; x < 200; x++) {
System.out.println(x);
}
}
}

测试类:

package threaddemos;
/**
* Created by gao on 16-1-3.
*/
public class ThreadDemo01 {
public static void main(String[] args) {
// 创建线程对象
// MyThread my = new MyThread();
// // 启动线程
// my.run();
// my.run();
// 调用run()方法为什么是单线程的呢?
// 因为run()方法直接调用其实就相当于普通的方法调用,所以你看到的是单线程的效果
// 面试题:run()和start()的区别?
// run():仅仅是封装被线程执行的代码,直接调用是普通方法
// start():首先启动了线程,然后再由jvm去调用该线程的run()方法。
// MyThread my = new MyThread();
// my.start();
// // IllegalThreadStateException:非法的线程状态异常
// // 为什么呢?因为这个相当于是my线程被调用了两次。而不是两个线程启动。
// my.start();
// 创建两个线程对象
MyThread my1 = new MyThread();
MyThread my2 = new MyThread();
my1.start();
my2.start();
}
}
  3)Thread类的基本获取和设置方法
        public final String getName():返回该线程的名称。
        public final void setName(String name):改变线程名称,使之与参数 name 相同。
        其实通过构造方法也可以给线程起名字
  4)获取main方法所在的线程名称
        public static Thread currentThread():返回对当前正在执行的线程对象的引用。
例子2:
自定义线程:

package threaddemos;
public class MyThread2 extends Thread {
public MyThread2() {
}
public MyThread2(String name) {
super(name);
}
@Override
public void run() {
for (int x = 0; x < 200; x++) {
System.out.println(getName() + "---" + x);
}
}
}

测试类:

package threaddemos;
/**
* Created by gao on 16-1-3.
*/
public class ThreadDemo02 {
public static void main(String[] args) {
// 创建线程对象
//无参构造+setXxx()
// MyThread2 my1 = new MyThread2();
// MyThread2 my2 = new MyThread2();
// my1.setName("林青霞");
// my2.setName("刘意");
// my1.start();
// my2.start();
//带参构造方法给线程起名字
MyThread2 my1 = new MyThread2("林青霞");
MyThread2 my2 = new MyThread2("刘意");
my1.start();
my2.start();
//获取main方法所在的线程对象的名称
//public static Thread currentThread():返回当前正在执行的线程对象
System.out.println(Thread.currentThread().getName());
}
}
/*
名称为什么是:Thread-? 编号
class Thread {
private char name[];
public Thread() {
init(null, null, "Thread-" + nextThreadNum(), 0);
}
private void init(ThreadGroup g, Runnable target, String name,
long stackSize) {
init(g, target, name, stackSize, null);
}
private void init(ThreadGroup g, Runnable target, String name,
long stackSize, AccessControlContext acc) {
//大部分代码被省略了
this.name = name.toCharArray();
}
public final void setName(String name) {
this.name = name.toCharArray();
}
private static int threadInitNumber; //0,1,2
private static synchronized int nextThreadNum() {
return threadInitNumber++; //return 0,1
}
public final String getName() {
return String.valueOf(name);
}
}
class MyThread extends Thread {
public MyThread() {
super();
}
}
*/
  5)实现方式2:声明实现 Runnable 接口的类。该类然后实现 run 方法。然后可以分配该类的实例,在创建 Thread 时作为一个参数来传递并启动。
            A:自定义类MyRunnable实现Runnable接口
            B:重写run()方法
            C:创建MyRunnable类的对象
            D:创建Thread类的对象,并把C步骤的对象作为构造参数传递
自定义类:

package threaddemos;
/**
* Created by gao on 16-1-4.
*/
public class MyRunnable implements Runnable {
@Override
public void run() {
for (int x = 0; x < 100; x++) {
// 由于实现接口的方式就不能直接使用Thread类的方法了,但是可以间接的使用
System.out.println(Thread.currentThread().getName() + "---" + x);
}
}
}

测试类:

package threaddemos;
/**
* Created by gao on 16-1-4.
*/
public class MyRunnableDemo {
public static void main(String[] args) {
// 创建MyRunnable类的对象
MyRunnable my = new MyRunnable();
// 创建Thread类的对象,并把C步骤的对象作为构造参数传递
// Thread(Runnable target)
// Thread t1 = new Thread(my);
// Thread t2 = new Thread(my);
// t1.setName("林青霞");
// t2.setName("刘意");
// Thread(Runnable target, String name)
Thread t1 = new Thread(my,"林青霞");
Thread t2 = new Thread(my,"刘意");
t1.start();
t2.start();
}
}
  6)多线程两种方式的图解比较和区别:

3、线程调度和线程控制
  1)线程调度
    假如我们的计算机只有一个 CPU,那么 CPU 在某一个时刻只能执行一条指令,线程只有得到 CPU时间片,也就是使用权,才可以执行指令。那么Java是
    如何对线程进行调用的呢?
    线程有两种调度模型:
      · 分时调度模型:所有线程轮流使用 CPU 的使用权,平均分配每个线程占用 CPU 的时间片.
      · 抢占式调度模型:优先让优先级高的线程使用 CPU,如果线程的优先级相同,那么会随机选择一个,优先级高的线程获取的 CPU 时间片相对多一些。
      · Java使用的是抢占式调度模型。
  2)设置和获取线程优先级
    · public final int getPriority():返回线程的优先级。
    · public final void setPriority(int newPriority):更改线程的优先级。

package threaddemos;
/**
* Created by gao on 16-1-4.
*/
/*
* 我们的线程没有设置优先级,肯定有默认优先级。
* 获取线程对象的优先级
* public final int getPriority():返回线程对象的优先级
* 设置线程对象的优先级
* public final void setPriority(int newPriority):更改线程的优先级。
*
* 注意:
* 线程默认优先级是5。
* 线程优先级的范围是:1-10。
* 线程优先级高仅仅表示线程获取的 CPU时间片的几率高,但是要在次数比较多,或者多次运行的时候才能看到比较好的效果。
*
* IllegalArgumentException:非法参数异常。
* 抛出的异常表明向方法传递了一个不合法或不正确的参数。
*/
public class ThreadPriorityDemo01 {
public static void main(String[] args) {
ThreadPriority tp1 = new ThreadPriority();
ThreadPriority tp2 = new ThreadPriority();
ThreadPriority tp3 = new ThreadPriority();
tp1.setName("东方不败");
tp2.setName("岳不群");
tp3.setName("林平之");
// 获取默认优先级
// System.out.println(tp1.getPriority()); //5
// System.out.println(tp2.getPriority());//5
// System.out.println(tp3.getPriority());//5
// 设置线程优先级(范围出错)
// tp1.setPriority(100000);
//设置正确的线程优先级
tp1.setPriority(10);
tp3.setPriority(1);
tp1.start();
tp2.start();
tp3.start();
}
}
  3)线程控制
        · 线程休眠
            public static void sleep(long millis):在指定的毫秒数内让当前正在执行的线程休眠(暂停执行),此操作受到系统计时器和调度程序精度和准确性的影响。
        · 线程加入
            public final void join():等待该线程终止。
        · 线程礼让
            public static void yield():暂停当前正在执行的线程对象,并执行其他线程。
        · 后台线程
            public final void setDaemon(boolean on):将该线程标记为守护线程或用户线程。当正在运行的线程都是守护线程时,Java 虚拟机退出。 该方法必须在启动线程前调用。 
        · 中断线程
            public final void stop():已过时。不建议使用
            public void interrupt():中断线程
例子1:
自定义Thread类:

package threaddemos;
import java.util.Date;
/**
* Created by gao on 16-1-4.
*/
public class ThreadSleep extends Thread {
public ThreadSleep() {
}
@Override
public void run() {
for (int x = 0; x < 100; x++) {
System.out.println(getName() + "---" + x + "日期:" + new Date());
//睡眠,1秒钟
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}

测试类:

package threaddemos;
/**
* Created by gao on 16-1-4.
*/
/*
* 线程休眠
* public static void sleep(long millis)
*/
public class ThreadSleepDemo {
public static void main(String[] args) {
ThreadSleep ts1 = new ThreadSleep();
ThreadSleep ts2 = new ThreadSleep();
ThreadSleep ts3 = new ThreadSleep();
ts1.setName("林青霞");
ts2.setName("林志玲");
ts3.setName("林志颖");
ts1.start();
ts2.start();
ts3.start();
ts3.start();
}
}
例子2:
ThreadJoin类:

package cn.itcast_04;
public class ThreadJoin extends Thread {
@Override
public void run() {
for (int x = 0; x < 100; x++) {
System.out.println(getName() + ":" + x);
}
}
}

测试类:

package cn.itcast_04;
/*
* public final void join():等待该线程终止。
*/
public class ThreadJoinDemo {
public static void main(String[] args) {
ThreadJoin tj1 = new ThreadJoin();
ThreadJoin tj2 = new ThreadJoin();
ThreadJoin tj3 = new ThreadJoin();
tj1.setName("李渊");
tj2.setName("李世民");
tj3.setName("李元霸");
tj1.start();
try {
tj1.join();
} catch (InterruptedException e) {
e.printStackTrace();
} tj2.start();
tj3.start();
}
}
例子3:
ThreadYield类:

package cn.itcast_04;
public class ThreadYield extends Thread {
@Override
public void run() {
for (int x = 0; x < 100; x++) {
System.out.println(getName() + ":" + x);
Thread.yield();
}
}
}

测试类:

package cn.itcast_04;
/*
* public static void yield():暂停当前正在执行的线程对象,并执行其他线程。
* 让多个线程的执行更和谐,但是不能靠它保证一人一次。
*/
public class ThreadYieldDemo {
public static void main(String[] args) {
ThreadYield ty1 = new ThreadYield();
ThreadYield ty2 = new ThreadYield();
ty1.setName("林青霞");
ty2.setName("刘意");
ty1.start();
ty2.start();
}
}

例子4:

package cn.itcast_04;
/*
* public final void setDaemon(boolean on):将该线程标记为守护线程或用户线程。
* 当正在运行的线程都是守护线程时,Java 虚拟机退出。 该方法必须在启动线程前调用。
*
* 游戏:坦克大战。
*/
public class ThreadDaemonDemo {
public static void main(String[] args) {
ThreadDaemon td1 = new ThreadDaemon();
ThreadDaemon td2 = new ThreadDaemon();
td1.setName("关羽");
td2.setName("张飞");
// 设置收获线程
td1.setDaemon(true);
td2.setDaemon(true);
td1.start();
td2.start();
Thread.currentThread().setName("刘备");
for (int x = 0; x < 5; x++) {
System.out.println(Thread.currentThread().getName() + ":" + x);
}
}
}
例子5:
ThreadStop类:

package cn.itcast_04;
import java.util.Date;
public class ThreadStop extends Thread {
@Override
public void run() {
System.out.println("开始执行:" + new Date());
// 我要休息10秒钟,亲,不要打扰我哦
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
// e.printStackTrace();
System.out.println("线程被终止了");
}
System.out.println("结束执行:" + new Date());
}
}

测试类:

package cn.itcast_04;
/*
* public final void stop():让线程停止,过时了,但是还可以使用。
* public void interrupt():中断线程。 把线程的状态终止,并抛出一个InterruptedException。
*/
public class ThreadStopDemo {
public static void main(String[] args) {
ThreadStop ts = new ThreadStop();
ts.start();
// 你超过三秒不醒过来,我就干死你
try {
Thread.sleep(3000);
// ts.stop();
ts.interrupt();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

4、线程生命周期

 
 
 
5、卖电影票案例
    1)方式一:继承Thread类
自定义类:

package threaddemos;
/**
* Created by gao on 16-1-4.
*/
public class SellTicket extends Thread {
// 定义100张票
// private int tickets = 100;
// 为了让多个线程对象共享这100张票,我们其实应该用静态修饰
private static int tickets = 100;
@Override
public void run() {
// 定义100张票
// 每个线程进来都会走这里,这样的话,每个线程对象相当于买的是自己的那100张票,这不合理,所以应该定义到外面
// int tickets = 100;
// 是为了模拟一直有票
while (true) {
if (tickets > 0) {
System.out.println(getName() + "---" + "正在出售第" + (tickets--) + "张票");
}
}
}
}

测试类:

package threaddemos;
/**
* Created by gao on 16-1-4.
*/
/*
* 某电影院目前正在上映贺岁大片(红高粱,少林寺传奇藏经阁),共有100张票,而它有3个售票窗口售票,请设计一个程序模拟该电影院售票。
* 继承Thread类来实现。
*/
public class SellTicketDemo {
public static void main(String[] args) {
// 创建三个线程对象
SellTicket st1 = new SellTicket();
SellTicket st2 = new SellTicket();
SellTicket st3 = new SellTicket();
// 给线程对象起名字
st1.setName("窗口1");
st2.setName("窗口2");
st3.setName("窗口3");
// 启动线程
st1.start();
st2.start();
st3.start();
}
}

    2)方式二:实现Runnable接口

自定义类:

package threaddemos;
/**
* Created by gao on 16-1-4.
*/
public class SellTicket2 implements Runnable {
private int tickets = 200;
@Override
public void run() {
while (true) {
if (tickets > 0) {
System.out.println(Thread.currentThread().getName() + "---" + "正在出售第" + (tickets--) + "张票");
}
}
}
}

测试类:

package threaddemos;
/**
* Created by gao on 16-1-4.
*/
/*
* 实现Runnable接口的方式实现
*/
public class SellTicketDemo2 {
public static void main(String[] args) {
// 创建资源对象
SellTicket2 st = new SellTicket2();
// 创建三个线程对象
Thread t1 = new Thread(st,"窗口1");
Thread t2 = new Thread(st,"窗口2");
Thread t3 = new Thread(st,"窗口3");
// 启动线程
t1.start();
t2.start();
t3.start();
}
}
 
6、线程同步
    1)出现的问题:
        · 相同的票出现多次:CPU的一次操作必须是原子性的
        · 还出现了负数的票:随机性和延迟导致的
    2)解决线程安全问题的基本思想
        · 首先想为什么出现问题?(也是我们判断是否有问题的标准)
            A:是否是多线程环境
            B:是否有共享数据
            C:是否有多条语句操作共享数据
        · 如何解决多线程安全问题呢?
            · 基本思想:让程序没有安全问题的环境。
            · 怎么实现呢?
                · 把多个语句操作共享数据的代码给锁起来,让任意时刻只能有一个线程执行即可。
    3)解决线程安全问题实现1:同步代码块
        格式:
    synchronized(对象){需要同步的代码;}
        同步可以解决安全问题的根本原因就在那个对象上。该对象如同锁的功能。
        同步代码块是把多条语句操作共享数据的代码的部分给包起来。

package threaddemos;
/**
* Created by gao on 16-1-4.
*/
public class SellTicket3 implements Runnable {
// 定义100张票
private int tickets = 50;
//创建锁对象
private Object obj = new Object();
@Override
public void run() {
while (true) {
synchronized (obj) {
if (tickets > 0) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()
+ "正在出售第" + (tickets--) + "张票");
}
}
}
}
// @Override
// public void run() {
//
// while (true) {
// if (tickets > 0) {
// System.out.println(Thread.currentThread().getName() + "---" + "正在出售第" + (tickets--) + "张票");
// }
// }
// }
}
测试类:
package threaddemos;
/**
* Created by gao on 16-1-4.
*/
/*
* 实现Runnable接口的方式实现
*/
public class SellTicketDemo3 {
public static void main(String[] args) {
// 创建资源对象
SellTicket3 st = new SellTicket3();
// 创建三个线程对象
Thread t1 = new Thread(st,"窗口1");
Thread t2 = new Thread(st,"窗口2");
Thread t3 = new Thread(st,"窗口3");
// 启动线程
t1.start();
t2.start();
t3.start();
}
}

   4)同步的特点

        · 同步的前提
            · 多个线程
            · 多个线程使用的是同一个锁对象
        · 同步的好处
            · 同步的出现解决了多线程的安全问题。
        · 同步的弊端
            · 当线程相当多时,因为每个线程都会去判断同步上的锁,这是很耗费资源的,无形中会降低程序的运行效率。
 
    5)解决线程安全问题实现2

package threaddemos;
/**
* Created by gao on 16-1-4.
*/
public class SellTicket4 implements Runnable {
// 定义100张票
private static int tickets = 100;
// 定义同一把锁
private Object obj = new Object();
private Demo d = new Demo();
private int x = 0;
//同步代码块用obj做锁
// @Override
// public void run() {
// while (true) {
// synchronized (obj) {
// if (tickets > 0) {
// try {
// Thread.sleep(100);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
// System.out.println(Thread.currentThread().getName()
// + "正在出售第" + (tickets--) + "张票 ");
// }
// }
// }
// }
//同步代码块用任意对象做锁
// @Override
// public void run() {
// while (true) {
// synchronized (d) {
// if (tickets > 0) {
// try {
// Thread.sleep(100);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
// System.out.println(Thread.currentThread().getName()
// + "正在出售第" + (tickets--) + "张票 ");
// }
// }
// }
// }
@Override
public void run() {
while (true) {
if(x%2==0){
//加载class文件当锁
synchronized (SellTicket.class) {
if (tickets > 0) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()
+ "正在出售第" + (tickets--) + "张票 ");
}
}
}else {
// synchronized (d) {
// if (tickets > 0) {
// try {
// Thread.sleep(100);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
// System.out.println(Thread.currentThread().getName()
// + "正在出售第" + (tickets--) + "张票 ");
// }
// }
sellTicket();
}
x++;
}
}
// private void sellTicket() {
// synchronized (d) {
// if (tickets > 0) {
// try {
// Thread.sleep(100);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
// System.out.println(Thread.currentThread().getName()
// + "正在出售第" + (tickets--) + "张票 ");
// }
// }
// }
//如果一个方法一进去就看到了代码被同步了,那么我就再想能不能把这个同步加在方法上呢?
// private synchronized void sellTicket() {
// if (tickets > 0) {
// try {
// Thread.sleep(100);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
// System.out.println(Thread.currentThread().getName()
// + "正在出售第" + (tickets--) + "张票 ");
// }
// }
private static synchronized void sellTicket() {
if (tickets > 0) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()
+ "正在出售第" + (tickets--) + "张票 ");
}
}
}
class Demo {
}

测试类:

package threaddemos;
/**
* Created by gao on 16-1-4.
*/
/*
* 实现Runnable接口的方式实现
*/
/*
* A:同步代码块的锁对象是谁呢?
* 任意对象。
*
* B:同步方法的格式及锁对象问题?
* 把同步关键字加在方法上。
*
* 同步方法是谁呢?
* this
*
* C:静态方法及锁对象问题?
* 静态方法的锁对象是谁呢?
* 类的字节码文件对象。
*/
public class SellTicketDemo4 {
public static void main(String[] args) {
// 创建资源对象
SellTicket3 st = new SellTicket3();
// 创建三个线程对象
Thread t1 = new Thread(st,"窗口1");
Thread t2 = new Thread(st,"窗口2");
Thread t3 = new Thread(st,"窗口3");
// 启动线程
t1.start();
t2.start();
t3.start();
}
}

    6)以往的线程安全类

package cn.itcast_12;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Hashtable;
import java.util.List;
import java.util.Vector;
public class ThreadDemo {
public static void main(String[] args) {
// 线程安全的类
StringBuffer sb = new StringBuffer();
Vector<String> v = new Vector<String>();
Hashtable<String, String> h = new Hashtable<String, String>();
// Vector是线程安全的时候才去考虑使用的,但是不会用Vector,而是用下面的。
// public static <T> List<T> synchronizedList(List<T> list)
List<String> list1 = new ArrayList<String>();// 线程不安全
List<String> list2 = Collections
.synchronizedList(new ArrayList<String>()); // 线程安全
}
}
 
 
 
 

Java API —— 多线程的更多相关文章

  1. Java API —— 多线程(2)

    1.JDK5中Lock锁的使用 虽然我们可以理解同步代码块和同步方法的锁对象问题,但是我们并没有直接看到在哪里加上了锁,在哪里释放了锁,为了更清晰的表达如何加锁和释放锁,JDK5以后提供了一个新的锁对 ...

  2. Java多线程--线程及相关的Java API

    Java多线程--线程及相关的Java API 线程与进程 进程是线程的容器,程序是指令.数据的组织形式,进程是程序的实体. 一个进程中可以容纳若干个线程,线程是轻量级的进程,是程序执行的最小单位.我 ...

  3. 已看1.熟练的使用Java语言进行面向对象程序设计,有良好的编程习惯,熟悉常用的Java API,包括集合框架、多线程(并发编程)、I/O(NIO)、Socket、JDBC、XML、反射等。[泛型]\

    1.熟练的使用Java语言进行面向对象程序设计,有良好的编程习惯,熟悉常用的Java API,包括集合框架.多线程(并发编程).I/O(NIO).Socket.JDBC.XML.反射等.[泛型]\1* ...

  4. Java API 快速速查宝典

    Java API 快速速查宝典 作者:明日科技,陈丹丹,李银龙,王国辉 著 出版社:人民邮电出版社 出版时间:2012年5月 Java编程的最基本要素是方法.属性和事件,掌握这些要素,就掌握了解决实际 ...

  5. java学习多线程之创建多线程一

    现在我们有这么一个需求,就是在主线程在运行的同时,我们想做其他的任务,这个时候我们就用到了多线程.那么如何创建多线程,我们知道在系统当中qq的多线程创建是由操作系统来完成的,那么如果我们想在java当 ...

  6. Java的多线程(上)

    多线程的优点和必要性是不言而喻的. 三种方法实现多线程 1. 继承Thread class A extends Thread{ public void run() {...} } 使用时, new A ...

  7. 跟着刚哥梳理java知识点——多线程(十六)

    创建多线程第一种方式:① 继承:继承Thread.② 重写:重写Thread类的run()方法③ 创建:创建一个子类的对象④ 调用:调用线程的start()方法,启动此线程,调用run()方法 cla ...

  8. java并发多线程显式锁Condition条件简介分析与监视器 多线程下篇(四)

    Lock接口提供了方法Condition newCondition();用于获取对应锁的条件,可以在这个条件对象上调用监视器方法 可以理解为,原本借助于synchronized关键字以及锁对象,配备了 ...

  9. Hbase框架原理及相关的知识点理解、Hbase访问MapReduce、Hbase访问Java API、Hbase shell及Hbase性能优化总结

    转自:http://blog.csdn.net/zhongwen7710/article/details/39577431 本blog的内容包含: 第一部分:Hbase框架原理理解 第二部分:Hbas ...

随机推荐

  1. 每日一“酷”之pprint

    pprint – 美观打印 作用:美观打印数据结构 pprint 包含一个“美观打印机”,用于生成数据结构的一个美观视图.格式化工具会生成数据结构的一些表示,不仅可以由解释器正确地解析,而且便于人类阅 ...

  2. 《C# 白话系列之——白话委托》读后记

    今天在博客圆首页看到一篇文章:<C# 白话系列之——白话委托> http://www.cnblogs.com/djangochina/p/3410002.html#commentform ...

  3. c++中new分配动态数组

    变长一维数组     这里说的变长数组是指在编译时不能确定数组长度,程序在运行时需要动态分配内存空间的数组.实现变长数组最简单的是变长一维数组,你可以这样做:  //文件名: array01.cpp ...

  4. Entity Framework Power Tools安装和使用

    Entity Framework Power Tools是一个由EntityFramework开发小组提供的工具,它可以从现有数据库生成Fluent款式的Code First代码. 大致来说,这个工具 ...

  5. Hashmap in java

    1. HashMap要点: 1.1 基本数据结构:  采用 数组+链表/平衡二叉查找树 的组合形式,所有键值对都以Entry<K,V>形式存储(每put进一个键值对,就会实例化一个Entr ...

  6. mysql中常用的公式及个人演示

    学生,院系表 -- phpMyAdmin SQL Dump-- version 4.1.9-- http://www.phpmyadmin.net---- Host: localhost-- Gene ...

  7. Windows Media Player安装了却不能播放网页上的视频

    前段时间遇到Windows Media Player安装了却不能播放网页上的视频的问题,在网上查找资料时,发现大部分资料都没能解决我这个问题.偶尔试了网上一牛人的方法,后来竟然解决了.现在再找那个网页 ...

  8. VBS基础篇 - Dictionary对象

    Dictionary是存储数据键和项目对的对象,其主要属性有Count.Item.Key,主要方法有Add.Exists.Items.Keys.Remove.RemoveAll. '建立字典 Dim ...

  9. Java 8 VM GC Tunning Guild Charter 9-b

    第九章 G1 GC The Garbage-First (G1) garbage collector is a server-style garbage collector, targeted for ...

  10. 典型的js页面

    var myurl; var mydata; var postype = "POST"; var getype = "GET"; var jsontype = ...