多线程实现
继承Thread
public static void main(String[] args) {
MyThread mt = new MyThread(); //4,创建Thread类的子类对象
mt.start(); //5,开启线程
for(int i = 0; i < 1000; i++) {
System.out.println("bb");
}
}
}
class MyThread extends Thread { //1,继承Thread
public void run() { //2,重写run方法
for(int i = 0; i < 1000; i++) { //3,将要执行的代码写在run方法中
System.out.println("aaaaaaaaaaaa");
}
}
实现Runnable
public static void main(String[] args) {
MyRunnable mr = new MyRunnable(); //4,创建Runnable的子类对象
//Runnable target = mr; mr = 0x0011
Thread t = new Thread(mr); //5,将其当作参数传递给Thread的构造函数
t.start(); //6,开启线程
for(int i = 0; i < 1000; i++) {
System.out.println("bb");
}
}
}
class MyRunnable implements Runnable { //1,定义一个类实现Runnable
@Override
public void run() { //2,重写run方法
for(int i = 0; i < 1000; i++) { //3,将要执行的代码写在run方法中
System.out.println("aaaaaaaaaaaa");
}
}
两种方式的区别)
查看源码的区别:
继承Thread
多线程(获取名字和设置名字)
多线程(获取当前线程的对象)
new Thread(new Runnable() {
public void run() {
for(int i = 0; i < 1000; i++) {
System.out.println(Thread.currentThread().getName() + "...aaaaaaaaaaaaaaaaaaaaa");
}
}
}).start();
new Thread(new Runnable() {
public void run() {
for(int i = 0; i < 1000; i++) {
System.out.println(Thread.currentThread().getName() + "...bb");
}
}
}).start();
Thread.currentThread().setName("我是主线程"); //获取主函数线程的引用,并改名字
System.out.println(Thread.currentThread().getName()); //获取主函数线程的引用,并获取名字
多线程(休眠线程)
new Thread() {
public void run() {
for(int i = 0; i < 10; i++) {
System.out.println(getName() + "...aaaaaaaaaaaaaaaaaaaaaa");
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
new Thread() {
public void run() {
for(int i = 0; i < 10; i++) {
System.out.println(getName() + "...bb");
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
同步代码块
单例设计模式
(1)恶汉式:内部先创建对象,可能会造成内存浪费
class Singleton {
//1,私有构造方法,其他类不能访问该构造方法了
private Singleton(){}
//2,创建本类对象
private static Singleton s = new Singleton();
//3,对外提供公共的访问方法
public static Singleton getInstance() { //获取实例
return s;
}
}
(2)懒汉式:内部先声明引用,不创建对象(开发时不用)
class Singleton {
//1,私有构造方法,其他类不能访问该构造方法了
private Singleton(){}
//2,声明一个引用
private static Singleton s ;
//3,对外提供公共的访问方法
public static Singleton getInstance() { //获取实例
if(s == null) { //判断,如果s是null就允许创建对象,不是null不创建
//多线程访问时会有安全问题,线程1等待,线程2等待
s = new Singleton();
}
return s;
}
}
(3)恶汉式和懒汉式的区别
1,恶汉式是空间换时间,懒汉式是时间换空间(不推荐)
2,在多线程访问时,恶汉式不会创建多个对象,而懒汉式可能会创建多个对象
3,无判断语句直接返回对象是恶汉式,有判断语句是懒汉式
计时器类Timer
Timer t = new Timer();
//在指定时间安排指定任务
t.schedule(new MyTimerTask(), new Date(118, 8, 1, 10, 21, 50),3000);
//第一个参数,是安排的任务,第二个参数是执行的时间,第三个参数是过多长时间再重复执行
线程通信
1.什么时候需要通信
ReentrantLock类 重入锁
1.同步
* 使用ReentrantLock类的lock()和unlock()方法进行同步
2.通信
* 使用ReentrantLock类的newCondition()方法可以获取Condition对象,从而可操作指定线程
* 需要等待的时候使用Condition的await()方法, 唤醒的时候用signal()方法
* 不同的线程使用不同的Condition, 这样就能区分唤醒的时候找哪个线程了
3.实例
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
public class Demo3_ReentrantLock {
/**
* @param args
*/
public static void main(String[] args) {
final Printer3 p = new Printer3();
new Thread() {
public void run() {
while(true) {
try {
p.print1();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
new Thread() {
public void run() {
while(true) {
try {
p.print2();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
new Thread() {
public void run() {
while(true) {
try {
p.print3();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
}
}
class Printer3 {
private ReentrantLock r = new ReentrantLock();
private Condition c1 = r.newCondition();
private Condition c2 = r.newCondition();
private Condition c3 = r.newCondition();
private int flag = 1;
public void print1() throws InterruptedException {
r.lock(); //获取锁
if(flag != 1) {
c1.await();
}
System.out.print("H");
System.out.print("e");
System.out.print("l");
System.out.print("l");
System.out.print("o");
System.out.print("\r\n");
flag = 2;
//this.notify(); //随机唤醒单个等待的线程
c2.signal();
r.unlock(); //释放锁
}
public void print2() throws InterruptedException {
r.lock();
if(flag != 2) {
c2.await();
}
System.out.print("e");
System.out.print("v");
System.out.print("e");
System.out.print("r");
System.out.print("y");
System.out.print("\r\n");
flag = 3;
//this.notify();
c3.signal();
r.unlock();
}
public void print3() throws InterruptedException {
r.lock();
if(flag != 3) {
c3.await();
}
System.out.print("d");
System.out.print("a");
System.out.print("y");
System.out.print("\r\n");
flag = 1;
c1.signal();
r.unlock();
}
}
Future> submit(Runnable task)
Future submit(Callable task)
Callable接口实现多线程程序实现
好处:
弊端: