单例设计模式
//饿汉式
class Singleton{
//私有构造方法,其他类不能访问该构造了
private Singleton() {}
private static Singleton s=new Singleton();
public static Singleton getInstance() {
return s;
}
}
//懒汉式
class Singleton{
//私有构造方法,其他类不能访问该构造了
private Singleton() {}
private static Singleton s;
public static Singleton getInstance() {
if(s==null) {
//线程1等待,线程2等待
s=new Singleton();
}
return s;
}
}
private static final Singleton s=new Singleton();
//单例的延迟加载模式
//饿汉式和懒汉式的区别
//饿汉式是空间换时间,懒汉式是时间换空间
//在多线程访问时,饿汉式不会创建多个对象,懒汉式可能会创建多个对象
Runtime的简单使用
//获取运行时对象
Runtime r = Runtime.getRuntime();
//设置自动关机,时间是秒
r.exec("shutdown -s -t 300");
//取消关机
r.exec("shutdown -a");
定时器Timer
Timer t = new Timer();
// 定时执行任务 初次执行时间 以后每隔多久执行一次
t.schedule(new MyTimer(), new Date(119,7,5,17,13,59),3000);
两个线程之间的相互通信
package com.java.thread;
public class Demo4 {
public static void main(String[] args) {
final Printer p = new Printer();
new Thread() {
public void run() {
while(true) {
try {
p.print1();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}.start();
new Thread() {
public void run() {
while(true) {
try {
p.print2();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}.start();
}
}
class Printer{
private int flag=1;
public void print1() throws InterruptedException {
synchronized (this) {
if(flag!=1) {
this.wait();
}
System.out.println("1");
System.out.println("11");
System.out.println("111");
System.out.println("1111");
System.out.println("11111");
flag=2;
//随机唤醒单个等待的线程
this.notify();
}
}
public void print2() throws InterruptedException {
synchronized (this) {
if(flag!=2) {
this.wait();
}
System.out.println("2");
System.out.println("22");
System.out.println("222");
System.out.println("2222");
System.out.println("22222");
flag=1;
this.notify();
}
}
}
三个和三个以上线程的通信
package com.java.thread;
public class Demo4 {
public static void main(String[] args) {
final Printer p = new Printer();
new Thread() {
public void run() {
while(true) {
try {
p.print1();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}.start();
new Thread() {
public void run() {
while(true) {
try {
p.print2();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}.start();
new Thread() {
public void run() {
while(true) {
try {
p.print3();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}.start();
}
}
class Printer{
private int flag=1;
public void print1() throws InterruptedException {
synchronized (this) {
while(flag!=1) {
this.wait();
}
System.out.println("1");
System.out.println("11");
System.out.println("111");
System.out.println("1111");
System.out.println("11111");
flag=2;
//随机唤醒单个等待的线程
this.notifyAll();
}
}
public void print2() throws InterruptedException {
synchronized (this) {
while(flag!=2) {
this.wait();
}
System.out.println("2");
System.out.println("22");
System.out.println("222");
System.out.println("2222");
System.out.println("22222");
flag=3;
this.notifyAll();
}
}
public void print3() throws InterruptedException {
synchronized (this) {
while(flag!=3) {
this.wait();
}
System.out.println("3");
System.out.println("33");
System.out.println("333");
System.out.println("3333");
System.out.println("33333");
flag=1;
this.notifyAll();
}
}
}
- 在同步代码块中,用哪个对象锁,就用哪个对象调用wait方法
- sleep方法必须传入参数,参数就是时间,时间到了自动醒来
- wait方法可以传入参数,也可以不传参数,传入参数就是在参数的时间结束后等待,不传入参数就是直接等待
- sleep方法在同步函数或同步代码块中,不释放锁
- wait在同步函数或者是同步代码块中释放锁
JDK1.5之后出现互斥锁ReentrantLock
package com.java.thread;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
public class Demo5 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Printer3 p = new Printer3();
new Thread() {
public void run() {
while(true) {
try {
p.print1();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}.start();
new Thread() {
public void run() {
while(true) {
try {
p.print2();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}.start();
new Thread() {
public void run() {
while(true) {
try {
p.print3();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
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.println("1");
System.out.println("11");
System.out.println("111");
System.out.println("1111");
System.out.println("11111");
flag=2;
c2.signal();
r.unlock();
}
public void print2() throws InterruptedException {
r.lock();
if(flag!=2) {
c2.await();
}
System.out.println("2");
System.out.println("22");
System.out.println("222");
System.out.println("2222");
System.out.println("22222");
flag=3;
c3.signal();
r.unlock();
}
public void print3() throws InterruptedException {
r.lock();
if(flag!=3) {
c3.await();
}
System.out.println("3");
System.out.println("33");
System.out.println("333");
System.out.println("3333");
System.out.println("33333");
flag=1;
c1.signal();
r.unlock();
}
}
线程组的使用
//默认的线程组为main
//创建新的线程组
ThreadGroup tg = new ThreadGroup("789");
MyRunnable mr = new MyRunnable();
//将线程t1放在组中。 线程组 线程 线程名
Thread t1 = new Thread(tg,mr,"123");
Thread t2 = new Thread(tg,mr,"456");
//获取组名
System.out.println(t1.getThreadGroup().getName());
System.out.println(t2.getThreadGroup().getName());
//将整个组设置成守护线程
tg.setDaemon(true);
线程池的简单使用
//创建线程池
ExecutorService pool = Executors.newFixedThreadPool(2);
pool.submit(new MyRunnable());
//将线程放进池子
pool.submit(new MyRunnable());
//关闭线程池
pool.shutdown();
第三种线程的实现方式
package com.java.thread;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class Demo8 {
public static void main(String[] args) throws InterruptedException, ExecutionException {
ExecutorService pool = Executors.newFixedThreadPool(2);
Future<Integer> f1 = pool.submit(new MyCallable(100));
Future<Integer> f2 = pool.submit(new MyCallable(50));
System.out.println(f1.get()+"..."+f2.get());
pool.shutdown();
}
}
class MyCallable implements Callable<Integer>{
private int num;
public MyCallable(int num) {
this.num=num;
}
@Override
public Integer call() throws Exception {
// TODO Auto-generated method stub
int sum=0;
for (int i = 0; i <= num; i++) {
sum+=i;
}
return sum;
}
}