1、多线程-单例设计模式:保证类在内存中只有一个对象。例如:(Runtime类)
a、控制类的创建,不让其他类来创建本类的对象。private
b、在本类中定义一个本类的对象。Singleton s;
c、提供公共的访问方式。 public static Singleton getInstance(){return s}
(1)饿汉式 开发用这种方式。
//饿汉式
class Singleton {
private Singleton(){}//1,私有构造函数,不能创建对象
private static Singleton s = new Singleton();//2,创建本类对象,定义static是为了可以使用 类名.方法 调用,定义private是为了不让其他类访问修改。
public static Singleton getInstance() { //3,对外提供公共的访问方法,定义static可以使用 类名.方法 调用,定义public为了让其他类调用。
return s;//返回这个对象
}
public static void print() {
System.out.println("abc");
}
}
内存中只有一个实例对象,导入的时候就创建好了
(2)懒汉式 面试写这种方式。存在多线程访问问题,不建议使用
//懒汉式
class Singleton {
private Singleton(){}//1,私有构造函数,不能创建对象
private static Singleton s = new Singleton();//2,创建本类对象,定义static是为了可以使用 类名.方法 调用,定义private是为了不让其他类访问修改。
public static Singleton getInstance() { //3,调用的时候判断。
if(s == null)
//可能存在 线程1,线程2 同时创建的问题
s = new Singleton();
return s;
}
public static void print() {
System.out.println("abc");
}
}
(3)第三种格式,比较简单
class Singleton {
private Singleton() {}
public static final Singleton s = new Singleton();//final是最终的意思,被final修饰的变量不可以被更改
}
Runtime就是一个单例设计模式
Runtime r = Runtime.getRuntime();
r.exec("shutdown -s -t 30"); //30秒后关机
2、多线程-Timer类):Timer类:计时器
public class Demo_Timer {
public static void main(String[] args) throws InterruptedException {
Timer t = new Timer();//创建Timer对象
t.schedule(new MyTimerTask(), new Date(114,9,15,10,54,20),3000);
while(true) {
System.out.println(new Date());
Thread.sleep(1000);
}
}
}
class MyTimerTask extends TimerTask {
@Override
public void run() {
System.out.println("时间到");
}
}
3、多线程-两个线程间通信
多个线程并发执行时, 在默认情况下CPU是随机切换线程的
如果我们希望他们有规律的执行, 就可以使用通信, 例如每个线程执行一次打印。
如果希望线程等待, 就调用wait()
如果希望唤醒等待的线程, 就调用notify();
这两个方法必须在同步代码中执行, 并且使用同步锁对象来调用
public class Demo1_Notify {
public static void main(String[] args) {
final Printer p = new Printer();
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();
}
}
//等待唤醒机制
class Printer {
private int flag = 1;
public void print1() throws InterruptedException {
synchronized(this) {
if(flag != 1) {
this.wait(); //当前线程等待
}
System.out.print("你");
System.out.print("好");
System.out.print("啊");
System.out.print("\r\n");
flag = 2;
this.notify(); //随机唤醒单个等待的线程
}
}
public void print2() throws InterruptedException {
synchronized(this) {
if(flag != 2) {
this.wait();
}
System.out.print("C");
System.out.print("S");
System.out.print("D");
System.out.print("N");
System.out.print("\r\n");
flag = 1;
this.notify();
}
}
}
4、多线程-互斥锁(JDK1.5的新特性)
使用ReentrantLock类的lock()和unlock()方法进行同步
通信
使用ReentrantLock类的newCondition()方法可以获取Condition对象
需要等待的时候使用Condition的await()方法, 唤醒的时候用signal()方法
不同的线程使用不同的Condition, 这样就能区分唤醒的时候找哪个线程了
public static void main(String[] args) {
final Printer3 p = new Printer3();
//创建3条线程
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();
//给每个线程设置不同的Condition对象
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("你");
System.out.print("好");
System.out.print("啊");
System.out.print("\r\n");
flag = 2;
//this.notify(); //随机唤醒单个等待的线程
c2.signal(); //唤醒等待线程2
r.unlock(); //释放锁
}
public void print2() throws InterruptedException {
r.lock();
if(flag != 2) {
c2.await();
}
System.out.print("C");
System.out.print("S");
System.out.print("D");
System.out.print("N");
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("1");
System.out.print("2");
System.out.print("3");
System.out.print("\r\n");
flag = 1;
c1.signal();
r.unlock();
}
a、控制类的创建,不让其他类来创建本类的对象。private
b、在本类中定义一个本类的对象。Singleton s;
c、提供公共的访问方式。 public static Singleton getInstance(){return s}
(1)饿汉式 开发用这种方式。
//饿汉式
class Singleton {
private Singleton(){}//1,私有构造函数,不能创建对象
private static Singleton s = new Singleton();//2,创建本类对象,定义static是为了可以使用 类名.方法 调用,定义private是为了不让其他类访问修改。
public static Singleton getInstance() { //3,对外提供公共的访问方法,定义static可以使用 类名.方法 调用,定义public为了让其他类调用。
return s;//返回这个对象
}
public static void print() {
System.out.println("abc");
}
}
内存中只有一个实例对象,导入的时候就创建好了
(2)懒汉式 面试写这种方式。存在多线程访问问题,不建议使用
//懒汉式
class Singleton {
private Singleton(){}//1,私有构造函数,不能创建对象
private static Singleton s = new Singleton();//2,创建本类对象,定义static是为了可以使用 类名.方法 调用,定义private是为了不让其他类访问修改。
public static Singleton getInstance() { //3,调用的时候判断。
if(s == null)
//可能存在 线程1,线程2 同时创建的问题
s = new Singleton();
return s;
}
public static void print() {
System.out.println("abc");
}
}
(3)第三种格式,比较简单
class Singleton {
private Singleton() {}
public static final Singleton s = new Singleton();//final是最终的意思,被final修饰的变量不可以被更改
}
Runtime就是一个单例设计模式
Runtime r = Runtime.getRuntime();
r.exec("shutdown -s -t 30"); //30秒后关机
2、多线程-Timer类):Timer类:计时器
public class Demo_Timer {
public static void main(String[] args) throws InterruptedException {
Timer t = new Timer();//创建Timer对象
t.schedule(new MyTimerTask(), new Date(114,9,15,10,54,20),3000);
while(true) {
System.out.println(new Date());
Thread.sleep(1000);
}
}
}
class MyTimerTask extends TimerTask {
@Override
public void run() {
System.out.println("时间到");
}
}
3、多线程-两个线程间通信
多个线程并发执行时, 在默认情况下CPU是随机切换线程的
如果我们希望他们有规律的执行, 就可以使用通信, 例如每个线程执行一次打印。
如果希望线程等待, 就调用wait()
如果希望唤醒等待的线程, 就调用notify();
这两个方法必须在同步代码中执行, 并且使用同步锁对象来调用
public class Demo1_Notify {
public static void main(String[] args) {
final Printer p = new Printer();
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();
}
}
//等待唤醒机制
class Printer {
private int flag = 1;
public void print1() throws InterruptedException {
synchronized(this) {
if(flag != 1) {
this.wait(); //当前线程等待
}
System.out.print("你");
System.out.print("好");
System.out.print("啊");
System.out.print("\r\n");
flag = 2;
this.notify(); //随机唤醒单个等待的线程
}
}
public void print2() throws InterruptedException {
synchronized(this) {
if(flag != 2) {
this.wait();
}
System.out.print("C");
System.out.print("S");
System.out.print("D");
System.out.print("N");
System.out.print("\r\n");
flag = 1;
this.notify();
}
}
}
4、多线程-互斥锁(JDK1.5的新特性)
使用ReentrantLock类的lock()和unlock()方法进行同步
通信
使用ReentrantLock类的newCondition()方法可以获取Condition对象
需要等待的时候使用Condition的await()方法, 唤醒的时候用signal()方法
不同的线程使用不同的Condition, 这样就能区分唤醒的时候找哪个线程了
public static void main(String[] args) {
final Printer3 p = new Printer3();
//创建3条线程
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();
//给每个线程设置不同的Condition对象
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("你");
System.out.print("好");
System.out.print("啊");
System.out.print("\r\n");
flag = 2;
//this.notify(); //随机唤醒单个等待的线程
c2.signal(); //唤醒等待线程2
r.unlock(); //释放锁
}
public void print2() throws InterruptedException {
r.lock();
if(flag != 2) {
c2.await();
}
System.out.print("C");
System.out.print("S");
System.out.print("D");
System.out.print("N");
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("1");
System.out.print("2");
System.out.print("3");
System.out.print("\r\n");
flag = 1;
c1.signal();
r.unlock();
}